Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';在这个节目中发生了什么,更重要的是,为什么?_Java_Multithreading_Concurrency - Fatal编程技术网

Java 什么';在这个节目中发生了什么,更重要的是,为什么?

Java 什么';在这个节目中发生了什么,更重要的是,为什么?,java,multithreading,concurrency,Java,Multithreading,Concurrency,请帮助我理解这个程序的执行,以及在更大的意义上,什么概念适用于这里?一个解释线程/堆栈创建和销毁的说明会很有帮助 class Joining { static Thread createThread(final int i, final Thread t1) { Thread t2 = new Thread() { public void run() { System.out.println(i+1);

请帮助我理解这个程序的执行,以及在更大的意义上,什么概念适用于这里?一个解释线程/堆栈创建和销毁的说明会很有帮助

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()));
    }
}

嗯……在我看来,
t1.join
将永远挂起第一个createThread(20,Thread.currentThread))调用。

Hmm……在我看来,
t1.join
将永远挂起第一个createThread(20,Thread.currentThread))调用

  • 内部createThread调用在主线程[M]的底部调用,参数为20和当前线程
  • 这个电话打印23张
  • 一个新的线程[A]被启动(并将被返回),该线程打印21,并等待主线程[M]死亡(并在主线程死亡后打印22)
  • 这个电话打印24。在新线程[A]打印21之前,不可能知道这是否会发生
  • 此调用返回新线程[A],该线程正在等待主线程[M]死亡
  • 新线程[A]作为第二个参数传递给createThread调用,其中10作为第一个参数
  • 这个电话打印了13张
  • 另一个新线程[B]被启动(虽然没有人捕捉到这个返回,但它将被返回),它打印11,并等待第一个创建的线程[A]死亡(在它死亡后将打印12)
  • 这个电话打印了14张。在第二个新线程[B]打印11之前,不可能知道这是否会发生
  • 此调用返回第二个新线程[B],该线程正在等待第一个创建的线程[A]死亡,但此返回调用没有执行任何操作
  • 主线程[M]没有要做的事情了,就死了
  • 当主线程[M]死亡时,对第一个创建的线程[A]的join()调用将返回
  • 第一个创建的线程[A]打印22
  • 第一个创建的线程[A]死亡
  • 当第一个创建的线程[A]死亡时,对第二个创建的线程[B]的join()调用将返回
  • 第二个创建的线程[B]打印12
  • 第二个创建的线程[B]死亡
  • JVM关闭,因为所有线程都已死亡
  • 内部createThread调用在主线程[M]的底部调用,参数为20和当前线程
  • 这个电话打印23张
  • 一个新的线程[A]被启动(并将被返回),该线程打印21,并等待主线程[M]死亡(并在主线程死亡后打印22)
  • 这个电话打印24。在新线程[A]打印21之前,不可能知道这是否会发生
  • 此调用返回新线程[A],该线程正在等待主线程[M]死亡
  • 新线程[A]作为第二个参数传递给createThread调用,其中10作为第一个参数
  • 这个电话打印了13张
  • 另一个新线程[B]被启动(虽然没有人捕捉到这个返回,但它将被返回),它打印11,并等待第一个创建的线程[A]死亡(在它死亡后将打印12)
  • 这个电话打印了14张。在第二个新线程[B]打印11之前,不可能知道这是否会发生
  • 此调用返回第二个新线程[B],该线程正在等待第一个创建的线程[A]死亡,但此返回调用没有执行任何操作
  • 主线程[M]没有要做的事情了,就死了
  • 当主线程[M]死亡时,对第一个创建的线程[A]的join()调用将返回
  • 第一个创建的线程[A]打印22
  • 第一个创建的线程[A]死亡
  • 当第一个创建的线程[A]死亡时,对第二个创建的线程[B]的join()调用将返回
  • 第二个创建的线程[B]打印12
  • 第二个创建的线程[B]死亡
  • 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
    

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

    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
    

    你想知道什么?如果执行代码会发生什么?你不明白什么?你想知道什么?如果执行代码会发生什么?你不明白什么?…直到主线程终止。然后“20”线程将终止,允许“10”线程加入“20”线程,然后终止。简而言之:t20等待main终止,t10等待t20终止,main终止,所以t20终止,所以t10终止……直到主线程终止。然后“20”线程将终止,允许“10”线程加入“20”线程,然后终止。简而言之:t20等待main终止,t10等待t20终止,main终止,所以t20终止,所以t10终止。在(3.)处启动线程后,即t2.start()为什么它总是在(4.)处执行下一行打印24。因为一旦启动线程,t2的run()将开始执行,并在24之前打印21,而不是打印24,这是不可能的。我在问为什么24始终是这里的输出,因为我们不知道jvm在这里是如何工作的。当执行
    t2.start()
    时,线程启动,调用立即返回。调用
    t2.start()
    的线程立即继续执行下一行。唯一未知的是JVM启动这个线程需要多长时间?这就是为什么我不知道21号还是24号会先打印出来。不过,它们将同时打印。在调用
    join()
    之前,新线程将与启动它的旧线程并行执行。两个线程都将运行并共享CPU周期。在多线程CPU或多核CPU或多CPU机器中,这些线程实际上可以同时执行。在(3.)处启动线程后,即t2.start()为什么它总是在(4.)处执行打印24的下一行。因为一旦你开始一个线程就不是了