2

如何使主要流程最后结束?

例如,我编写了一些代码,创建了一个 Thread: Test,他创建了另外三个线程 - Test2,但 main 在Test开始之前完成了。

public class Test implements Runnable{
    String url;
    Thread mThread;

    public Test(String url) {
        this.url = url;        
    }

    public void start(){
       this.mThread = new Thread(this);
       this.mThread.start();
    }

     @Override
    public void run() {
        System.out.println("TEST STARTED!");
        Test2 wclw[] = new Test2[3];

            for (int i = 0; i < wclw.length; i++) {
                wclw[i] = new Test2(url, i + 1);
                wclw[i].start();
            }
    }

    public static void main(String[] args) throws IOException {
        System.out.println("MAin STARTED!");
        (new Test("qwerty")).start();

        System.out.println("MAIN FINISHED");
    }
}

class Test2 implements Runnable{
    String url;
    int threadNum;
    Thread mThread;

    public Test2(String url, int threadNum) {
        this.url = url;
    }

    public void start(){
        this.mThread = new Thread(this);
        this.mThread.start();
    }   

    @Override
    public void run() {
         System.out.println("TEST2 STARTED!");   
         for (int i = 0; i < 2; i++) {
            System.out.println(url);
        }
    }
}

输出:

MAin STARTED! 
MAIN FINISHED 
TEST STARTED!
qwerty
TEST2 STARTED!
TEST2 STARTED!
qwerty
qwerty 
TEST2 STARTED!
qwerty 
qwerty
qwerty
4

3 回答 3

11

如何使主要流程最后结束?

我假设您的意思是主线程。你需要使用thread.join(). 您的主线程应该加入它产生的线程,而子线程也需要加入它产生的线程。 thread.join()在继续之前等待线程完成。

Test test = new Test("qwerty");
// start the test thread running in the background
test.start();
// do other stuff on the main thread
...
// wait for the test thread to finish
test.mThread.join();

在测试线程中,您应该执行以下操作:

// start other threads
for (int i = 0; i < wclw.length; i++) {
    wclw[i] = new Test2(url, i + 1);
    wclw[i].start();
}
// do other stuff in the test thread if necessary
...
// come back and wait for them all to finish
for (int i = 0; i < wclw.length; i++) {
    wclw[i].mthread.join();
}

所以子线程将等待它产生的每个线程完成,然后它会完成。主线程将等待子线程完成,然后将最后完成。

仅供参考:在子线程之前完成主线程不是问题。子线程不是守护线程,因此 JVM 将在 JVM 关闭之前等待它们完成。

于 2013-05-17T21:23:25.057 回答
2

使用 Thread#join 调用等待其他线程完成:

System.out.println("MAin STARTED!");
Test t = new Test("qwerty");
t.start();
t.mThread.join();
System.out.println("MAIN FINISHED");
于 2013-05-17T21:25:06.960 回答
1

您还可以使用正在运行的线程的“守护程序”属性来解决此问题。

用 Java 思考 - 守护线程

“守护程序”线程是指只要程序正在运行就应该在后台提供一般服务的线程,但它不是程序本质的一部分。因此,当所有非守护线程完成时,程序终止。相反,如果有任何非守护线程仍在运行,则程序不会终止。

方法Test.start应该修改如下:

public void start(){
   this.mThread = new Thread(this);
   this.mThread.setDaemon(false); // This method must be called before the thread is started.
   this.mThread.start();
}
于 2013-05-18T00:05:41.930 回答