java - thread.join() 的线程完成时间
问题描述
目前在生产应用程序中使用线程。我想知道 - 如果线程都具有相同定义的静态工作负载,它们会按顺序完成和挂起吗?例如,如果我在循环中创建线程 1、线程 2、线程 3 并让它们添加最多 1,000 的值,它们是否总是按照创建的顺序完成?
我使用 join() 方法对该理论进行了一些测试,该理论(表面上)似乎是正确的。
public class ThreadingMain implements Runnable{
public static int total;
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < 15; i++) {
Thread t = new Thread(new ThreadingMain(), i+"");
t.start();
t.join();
}
}
@Override
public void run() {
add();
}
private static void add() {
int i = 100000;
for(int j = 0; j < i; j++) {
total += j;
}
System.out.println(Thread.currentThread().getName() + " finished");
}
}
我得到以下输出:
0 finished
1 finished
2 finished
...
12 finished
13 finished
14 finished
正如预期的那样,删除 join() 不再是这种情况。
本质上,具有相同工作负载的线程是否总是按顺序完成?这有什么变数吗?
解决方案
由于 CPU 具有有限数量的内核和一次可能执行的线程,操作系统需要管理线程何时以及多长时间获得 CPU 执行时间。这是由操作系统的调度程序完成的。
在这里您可以阅读一些相关信息:操作系统中的 CPU 调度
您的操作系统如何管理线程是您无法从代码中有效影响的事情。你不能保证,比如说,线程A
会在线程之前完成,B
即使A
是在之前创建B
的。
同样,请记住,您创建的线程并不是操作系统一次管理的唯一线程。还有更多的进程/程序不属于您的代码,但参与了调度。
推荐阅读
- sql - Postgres ERROR "UTF8" 中的编码问题是最好将编码设置为 UTF8 还是使数据与 WIN1252 兼容?
- exception - RISC-V 从带有压缩指令的异常处理程序返回
- amazon-web-services - CloudFormation::APIGateway 中的 AWS 和 AWS_PROXY 有什么区别?
- javascript - JavaScript将数组分成两半将前半部分与后半部分并列
- r - 向量化函数/提高 data.table 中的计算速度
- go - 工作池实现以限制每秒的 http 请求
- cgal - 无法使用 brew install cgal-qt5 安装 cgal-qt5
- azure-active-directory - 更改 Azure AD 的所有者
- c++ - 不知道如何在家庭作业任务中实现一个东西
- linux - 复制用于 GUI 粘贴的终端输出