如何在所有子线程完成执行后运行主线程
how to run the main thread after all child threads have completed there exceution
我有一个需求,其中28个线程必须完成一些功能。我在匿名内部 类 中创建了这些线程,例如 :
Thread t=new Thread(new Runnable(){public void run()
{//code
}}
);
t.start();
现在我希望在所有这些线程完成工作后开始进一步执行。
注意:我对 join() 方法感到困惑,因为它使我的线程 运行 顺序进行。
所以谁能建议我如何在这些线程完成工作后创建主线程 运行。
使用 CountDownLatch
并等待所有线程完成。 :) .
PS :我必须同意,使用 join()
也是正确且更有效的。
示例代码:
public static void main(String[] args) throws InterruptedException {
线程 t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t1 : " + i);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t2 : " + i);
}
}
});
t2.start();
t1.join();
t2.join();
System.out.println("main");
}
O/P :
t1 : 0
t1 : 1
t2 : 0
t1 : 2
t1 : 3
t2 : 1
t1 : 4
t1 : 5
t2 : 2
t1 : 6
t1 : 7
t2 : 3
t1 : 8
t1 : 9
t2 : 4
t2 : 5
t2 : 6
t2 : 7
t2 : 8
t2 : 9
main
Note : I am confused about join() method as it makes my threads run sequentially.
如果您有这样的代码,它将执行此操作:
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
t.join();
}
但是,您可以并行启动所有想要 运行 的线程,然后 对它们全部调用 join
。例如:
List<Thread> threads = new ArrayList<>();
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
threads.add(t);
}
// Now everything's running - join all the threads
for (Thread thread : threads) {
thread.join();
}
// Now you can do whatever you need to after all the
// threads have finished.
当然还有许多其他方法 - 直接启动线程在您的代码中可能不如使用更高级别的抽象那么合适;这取决于您要实现的目标。上面的应该工作正常 - 假设所有 Runnable
s 能够并行 运行 而不会通过同步相互阻塞。
根据您为加入提供的行为,我猜您是在一个循环中启动和加入线程。
如果您查看 this page 上的 javadoc,您会注意到对 join 的调用将停止调用线程的执行,直到另一个线程完成执行。
您可能希望在创建线程时保留一个线程数组或列表,并在一个循环中启动它们,然后才将它们全部加入。
Thread[] workers = new Thread[28];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Thread { ... };
}
// Start running all threads
for (Thread worker: workers) {
worker.start();
}
// Make sure all threads are completed
for (Thread worker: workers) {
worker.join(); // if the worker already stopped, it'll return immediately.
}
// Now all threads have finished running and you can start post-processing
这不是最优雅的解决方案,但可以解决问题。
正如其他人所提到的,您可能应该使用 CountDownLatch(还没有使用过,所以我无法提供反馈)
编辑:我被 Jon Skeet 打败了,抱歉回答多余...
public static void main(String... args) {
final CountDownLatch latch = new CountDownLatch(28);
for(int i=0;i<28;i++) {
Thread t=new Thread(new Runnable(){
public void run()
{
try {
//code
} finally {
latch.countDown();
}
}
});
t.start();
}
latch.await();
// Continue Code
}
CountDownLatch 是更好的选择。
我创建了虚拟程序。
在这个程序中,我总计 1000 个数字。我创建了 10 个线程。在主线程中,我正在做所有子线程总和的穹顶。看代码你就明白了。
package Test1;
import java.util.concurrent.CountDownLatch;
class Sum extends Thread {
private int from;
private int to;
private int sum = 0;
CountDownLatch latch;
public int getSum() {
return sum;
}
public Sum(int from, int to, CountDownLatch latch) {
this.from = from;
this.to = to;
this.latch = latch;
}
public void run() {
for (int i = from; i < to; i++) {
sum += i;
}
latch.countDown();
}
}
public class Test5 {
public static void main(String[] args) throws InterruptedException {
int n = 1000;
int tn = 10;
int from = 1;
int to;
int sum = 0;
Sum[] sumArray = new Sum[tn];
final CountDownLatch latch = new CountDownLatch(tn);
for (int i = 0; i < tn; i++) {
to = from + n / tn;
Sum s = new Sum(from, to, latch);
sumArray[i] = s;
s.start();
from = to;
}
// Thread.sleep(1000);
latch.await();
for (int i = 0; i < tn; i++) {
sum += sumArray[i].getSum();
}
System.out.println(sum);
}
}
我有一个需求,其中28个线程必须完成一些功能。我在匿名内部 类 中创建了这些线程,例如 :
Thread t=new Thread(new Runnable(){public void run()
{//code
}}
);
t.start();
现在我希望在所有这些线程完成工作后开始进一步执行。
注意:我对 join() 方法感到困惑,因为它使我的线程 运行 顺序进行。
所以谁能建议我如何在这些线程完成工作后创建主线程 运行。
使用 CountDownLatch
并等待所有线程完成。 :) .
PS :我必须同意,使用 join()
也是正确且更有效的。
示例代码:
public static void main(String[] args) throws InterruptedException { 线程 t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t1 : " + i);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t2 : " + i);
}
}
});
t2.start();
t1.join();
t2.join();
System.out.println("main");
}
O/P :
t1 : 0
t1 : 1
t2 : 0
t1 : 2
t1 : 3
t2 : 1
t1 : 4
t1 : 5
t2 : 2
t1 : 6
t1 : 7
t2 : 3
t1 : 8
t1 : 9
t2 : 4
t2 : 5
t2 : 6
t2 : 7
t2 : 8
t2 : 9
main
Note : I am confused about join() method as it makes my threads run sequentially.
如果您有这样的代码,它将执行此操作:
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
t.join();
}
但是,您可以并行启动所有想要 运行 的线程,然后 对它们全部调用 join
。例如:
List<Thread> threads = new ArrayList<>();
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
threads.add(t);
}
// Now everything's running - join all the threads
for (Thread thread : threads) {
thread.join();
}
// Now you can do whatever you need to after all the
// threads have finished.
当然还有许多其他方法 - 直接启动线程在您的代码中可能不如使用更高级别的抽象那么合适;这取决于您要实现的目标。上面的应该工作正常 - 假设所有 Runnable
s 能够并行 运行 而不会通过同步相互阻塞。
根据您为加入提供的行为,我猜您是在一个循环中启动和加入线程。
如果您查看 this page 上的 javadoc,您会注意到对 join 的调用将停止调用线程的执行,直到另一个线程完成执行。
您可能希望在创建线程时保留一个线程数组或列表,并在一个循环中启动它们,然后才将它们全部加入。
Thread[] workers = new Thread[28];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Thread { ... };
}
// Start running all threads
for (Thread worker: workers) {
worker.start();
}
// Make sure all threads are completed
for (Thread worker: workers) {
worker.join(); // if the worker already stopped, it'll return immediately.
}
// Now all threads have finished running and you can start post-processing
这不是最优雅的解决方案,但可以解决问题。 正如其他人所提到的,您可能应该使用 CountDownLatch(还没有使用过,所以我无法提供反馈)
编辑:我被 Jon Skeet 打败了,抱歉回答多余...
public static void main(String... args) {
final CountDownLatch latch = new CountDownLatch(28);
for(int i=0;i<28;i++) {
Thread t=new Thread(new Runnable(){
public void run()
{
try {
//code
} finally {
latch.countDown();
}
}
});
t.start();
}
latch.await();
// Continue Code
}
CountDownLatch 是更好的选择。
我创建了虚拟程序。 在这个程序中,我总计 1000 个数字。我创建了 10 个线程。在主线程中,我正在做所有子线程总和的穹顶。看代码你就明白了。
package Test1;
import java.util.concurrent.CountDownLatch;
class Sum extends Thread {
private int from;
private int to;
private int sum = 0;
CountDownLatch latch;
public int getSum() {
return sum;
}
public Sum(int from, int to, CountDownLatch latch) {
this.from = from;
this.to = to;
this.latch = latch;
}
public void run() {
for (int i = from; i < to; i++) {
sum += i;
}
latch.countDown();
}
}
public class Test5 {
public static void main(String[] args) throws InterruptedException {
int n = 1000;
int tn = 10;
int from = 1;
int to;
int sum = 0;
Sum[] sumArray = new Sum[tn];
final CountDownLatch latch = new CountDownLatch(tn);
for (int i = 0; i < tn; i++) {
to = from + n / tn;
Sum s = new Sum(from, to, latch);
sumArray[i] = s;
s.start();
from = to;
}
// Thread.sleep(1000);
latch.await();
for (int i = 0; i < tn; i++) {
sum += sumArray[i].getSum();
}
System.out.println(sum);
}
}