繁体   English   中英

该程序中发生了什么,更重要的是,为什么?

[英]What's going on in this program, and, more importantly, why?

请帮助我了解该程序的执行情况,从广义上讲,哪些概念适用于此? 解释线程/堆栈的创建和销毁的图示可能会有所帮助。

class Joining {

    static Thread createThread(final int i, final Thread t1) {
        Thread t2 = new Thread() {
            public void run() {
                System.out.println(i+1);
                try {
                    t1.join(); 
                } catch (InterruptedException ie) {
                }
                System.out.println(i+2);
            }
        };
        System.out.println(i+3);
        t2.start(); //1
        System.out.println(i+4);
        return t2;
    }
    public static void main(String[] args) {
        createThread(10, createThread(20, Thread.currentThread()));
    }
}
  1. 内部createThread调用从主线程[M]的底部调用,并带有参数20和当前线程。
  2. 该呼叫打印23。
  3. 一个新的线程[A]被启动(将返回),它打印21,并等待主线程[M]死(在完成后将打印22)。
  4. 此调用将打印24。无法知道是否会在新线程[A]打印21之前发生。
  5. 该调用返回新线程[A],该线程正在等待主线程[M]终止。
  6. 新线程[A]作为第二个参数传递给createThread调用,第一个参数为10。
  7. 该呼叫将打印13。
  8. 启动另一个新线程[B](尽管没有人捕捉到此返回,但将返回该线程),该线程将打印11,并等待第一个创建的线程[A]死(此后将打印12)。
  9. 该调用将打印14。不可能知道是否会在第二个新线程[B]打印11之前发生。
  10. 该调用返回第二个新线程[B],该线程正在等待第一个创建的线程[A]终止,但是此返回调用未执行任何操作。
  11. 主线程[M]用尽了所有资源,然后死掉了。
  12. 当主线程[M]死时,对第一个创建的线程[A]的join()调用返回。
  13. 创建的第一个线程[A]打印22。
  14. 创建的第一个线程[A]死亡。
  15. 当第一个创建的线程[A]死亡时,对第二个创建的线程[B]的join()调用返回。
  16. 创建的第二个线程[B]打印12。
  17. 创建的第二个线程[B]死亡。
  18. JVM关闭,因为所有线程都已死亡。

添加一些调试输出可能会帮助您理解执行:

import static java.lang.Thread.currentThread;

class Joining {

    static int count = 0;

    static Thread createThread(final int i, final Thread t1) {
        System.out.println("Create thread with " + i + " and " + t1.getName());
        Thread t2 = new Thread("Thread " + count++) {
            public void run() {
                System.out.println(currentThread().getName() + ": " + (i+1));
                try {
                    System.out.println(currentThread().getName() + ": join with " + t1.getName());
                    t1.join(); 
                } catch (InterruptedException ie) {
                }
                System.out.println(currentThread().getName() + ": " + (i+2));
            }
        };
        System.out.println(currentThread().getName() + ": " + (i+3));
        System.out.println(currentThread().getName() + ": starting thread " + t2.getName());
        t2.start(); //1
        System.out.println(currentThread().getName() + ": " + (i+4));
        return t2;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread someThread = createThread(20, currentThread());
        System.out.println("After first createThread.");
        Thread.sleep(1000);
        createThread(10, someThread);
    }
}

输出是

Create thread with 20 and main
main: 23
main: starting thread Thread 0
main: 24
After first createThread.
Thread 0: 21
Thread 0: join with main
Create thread with 10 and Thread 0
main: 13
main: starting thread Thread 1
main: 14
Thread 1: 11
Thread 1: join with Thread 0
Thread 0: 22
Thread 1: 12

嗯...对我来说好像t1.join会永远挂在第一个createThread(20,Thread.currentThread))调用上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM