Java 为什么可以';线程停止工作后,我是否运行main()中的语句?
所以我有一个有4个线程的程序,所有线程都在运行。 其中3个线程始终在运行,即使程序完成其工作时也是如此。 所以我创建了一些变量,让它们停止 我将Java 为什么可以';线程停止工作后,我是否运行main()中的语句?,java,multithreading,parallel-processing,Java,Multithreading,Parallel Processing,所以我有一个有4个线程的程序,所有线程都在运行。 其中3个线程始终在运行,即使程序完成其工作时也是如此。 所以我创建了一些变量,让它们停止 我将while(true)更改为while(exit),程序运行正常 在线程之后,我想运行一些其他语句,但前提是线程已经停止 我尝试使用4个变量,exit、exit1、exit2、exit3,并将它们设置为false。线程将完成并使这些变量为真 大体上,在Thread.start()之后,如果我想打印一些东西,它不会打印 Thread1.start(); T
while(true)
更改为while(exit)
,程序运行正常
在线程之后,我想运行一些其他语句,但前提是线程已经停止
我尝试使用4个变量,exit、exit1、exit2、exit3,并将它们设置为false。线程将完成并使这些变量为真
大体上,在Thread.start()
之后,如果我想打印一些东西,它不会打印
Thread1.start();
Thread2.start();
Thread3.start();
Thread4.start();
// System.out.println("Program Ended") --> If i do this, it prints before
// the threads
if(exit && exit2 && exit3 && exit4) {
System.out.println("Program Ended");
// code here
}
有没有办法确保我只在线程停止后才运行某些语句?Thread类有一个方法可以执行该操作,因为您将一直阻止,直到线程完成执行。教程如何使用
Thread#join
因此,您的代码应该如下所示:
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
if(exit && exit2 && exit3 && exit4) {
System.out.println("Program Ended");
}
您的if块不能保证在所有线程之后运行。您必须通过对每个线程调用
thread.join()
,显式地使主线程等待这些线程:
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
if (exit && exit2 && exit3 && exit4) {
System.out.println("Program Ended");
}
<>这将确保<代码>如果块只在每个线程都已死亡之后运行。 < P>作为替代,您应该考虑<代码> CyclicBarrier < /C> >或<代码> CurtDutLaCH < /C>。 与自定义终止线程标志相比,这些标志不太容易出错,通常不太详细,效率也相当高 它们有各自的特点,但非常接近。
CountDownLatch
将“倒计时”操作的计数器关联到reach以继续,而CyclicBarrier
将调用wait()
以应用特定处理的不同线程的计数器关联到reach
使用CyclicBarrier
它可能看起来像:
CyclicBarrier barrier = new CyclicBarrier(4, () -> {
System.out.println("Program Ended");
});
此处4
是必须在屏障上等待的线程数,当4个不同的线程“到达”屏障时,将显示“程序结束”
螺纹在加工后可到达屏障,例如:
new Thread(() -> {
while (!done()) {
....
}
barrier.await(); // replace the flag boolean
});
请注意,屏障是循环的。这意味着它可以在激活后重新使用。与
CountDownLatch
相反,当有很多线程时,使用ThreadGroup
来管理多个线程可能更优雅、更方便
示例代码:
ThreadGroup tg = new ThreadGroup("runner");
new Thread(tg, () -> {
// ...
}, "t-1").start();
new Thread(tg, () -> {
// ...
}, "t-2").start();
// create more threads,
Thread[] tArr = new Thread[tg.activeCount()];
cg.enumerate(tArr); // get threads,
// wait all consumers to finish,
for (Thread t : tArr) {
t.join();
}
提示:
- 创建新线程时,请在构造函数中指定线程组
- 启动所有子线程后,从线程组中获取线程,并在每个线程上加入
将只返回尚未终止的线程ThreadGroup.activeCount()