Java 等待线程

Java 等待线程,java,multithreading,wait,Java,Multithreading,Wait,我有一个包含以下(Java)代码的方法: doSomeThings()创建一些线程,每个线程只运行有限的时间。问题是我不希望在doSomeThings()启动的所有线程完成之前调用doSomeThings()。(另外,doSomeThings()将调用可能启动新线程的方法等等。在所有这些线程完成之前,我不想执行doSomeOtherThings()) 这是因为doSomeThings()等将myObject设置为null,而doSomeOtherThings()调用myObject.myMeth

我有一个包含以下(Java)代码的方法:

doSomeThings()
创建一些线程,每个线程只运行有限的时间。问题是我不希望在
doSomeThings()
启动的所有线程完成之前调用
doSomeThings()。(另外,
doSomeThings()
将调用可能启动新线程的方法等等。在所有这些线程完成之前,我不想执行
doSomeOtherThings()

这是因为
doSomeThings()
等将
myObject
设置为
null
,而
doSomeOtherThings()
调用
myObject.myMethod()
,我当时不希望
myObject
null


有没有一些标准的方法来做这种事情(在Java中)?

看看
Thread.join()
方法

我不清楚您的具体实现,但doSomeThings()似乎应该在返回之前等待子线程

在doSomeThings()方法内部,通过调用Thread.join()方法等待线程

当您创建一个线程并调用该线程的join()方法时,调用线程将等待该线程对象死亡

例如:

// Create an instance of my custom thread class
MyThread myThread = new MyThread();
// Tell the custom thread object to run
myThread.start();
// Wait for the custom thread object to finish
myThread.join();

您可能想看看
java.util.concurrent
包。特别是,您可以考虑使用<代码> CurtDutLabCH < /C> >

package de.grimm.game.ui;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

public static void main(String[] args) 
throws Exception {

    final ExecutorService executor = Executors.newFixedThreadPool(5);
    final CountDownLatch latch = new CountDownLatch(3);

    for( int k = 0; k < 3; ++k ) {

        executor.submit(new Runnable() {
            public void run() {
                // ... lengthy computation...
                latch.countDown();
            }
        });
    }

    latch.await();

    // ... reached only after all threads spawned have
    // finished and acknowledged so by counting down the
    // latch.

    System.out.println("Done");
}
}

您可能需要添加异常处理(
interruptedexception
)和一些类似的处理。

您正在查找的是Executor服务并使用futures:)


因此,基本上收集提交给executor服务的所有Runnable的未来。循环所有未来并调用get()方法。当相应的runnable完成时,这些将返回。

另一个选项是休眠主线程,并让它经常检查其他线程是否完成。然而,我更喜欢德克和马库斯·亚当斯的答案——为了完整起见,这里就把它抛到这里。

另一个有用的、更健壮的、与倒计时闩锁功能类似的功能是。它的工作原理类似于倒计时闩锁,您必须知道使用了多少个参与方(线程),但它允许您在每次创建倒计时闩锁的新实例时重用该屏障


我非常喜欢momania的建议,即使用ExecutorService,收集期货并调用get on所有这些服务,直到它们完成

取决于你在这里到底想做什么。您主要关心的是动态确定从
doSomeThings()
中调用的连续方法生成的各种线程,然后能够等到它们完成后再调用
dosometherthings()
?或者可以知道编译时生成的线程?在后一种情况下,有很多解决方案,但基本上都涉及从创建线程的任何位置对所有这些线程调用
Thread.join()
方法

如果确实是前者,那么最好使用
ThreadGroup
及其
enumerate()

方法。如果已将新线程正确添加到线程组,则这将为您提供doSomeThings()生成的所有线程的数组。然后,您可以循环遍历返回数组中的所有线程引用,并在调用
doSomeOtherThings()

-1调用myThread.run不会启动新线程之前,在主线程上调用
join()
。myThread.run()完成时调用myThread.join()只是因为程序顺序,而不是因为任何异步reason@Donal哎呀。谢谢我更新了答案@约翰,对不起,是打字错误。我习惯于从Runnable而不是线程继承。(+1)
CountdownLatch
非常方便
package de.grimm.game.ui;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

public static void main(String[] args) 
throws Exception {

    final ExecutorService executor = Executors.newFixedThreadPool(5);
    final CountDownLatch latch = new CountDownLatch(3);

    for( int k = 0; k < 3; ++k ) {

        executor.submit(new Runnable() {
            public void run() {
                // ... lengthy computation...
                latch.countDown();
            }
        });
    }

    latch.await();

    // ... reached only after all threads spawned have
    // finished and acknowledged so by counting down the
    // latch.

    System.out.println("Done");
}
}
boolean done = false;

void functionRunInThreadA() {

    synchronized( commonLock ) {

        while( !done ) commonLock.wait();
    }

    // Here it is safe to set the variable to null
}

void functionRunInThreadB() {

    // Do something...

    synchronized( commonLock ) {
        done = true;
        commonLock.notifyAll();
    }
}