美文网首页
《java多线程编程核心技术》-----使用jion()方法时,

《java多线程编程核心技术》-----使用jion()方法时,

作者: 弱弱的弱 | 来源:发表于2018-12-22 16:35 被阅读0次

    在读到《java多线程编程核心技术》的3.2节“jion方法的使用”的时候,看到如下代码,便有了这篇总结的文章。


    TheadA.java:

    public class ThreadA extends Thread {
        private ThreadB b;
    
        public ThreadA(ThreadB b) {
            super();
            this.b = b;
        }
    
        @Override
        public void run() {
            try {
                synchronized (b) {
                    System.out.println("begin A ThreadName="
                            + Thread.currentThread().getName() + "  "
                            + System.currentTimeMillis());
                    Thread.sleep(5000);
                    System.out.println("  end A ThreadName="
                            + Thread.currentThread().getName() + "  "
                            + System.currentTimeMillis());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    ThreadB.java:

    public class ThreadB extends Thread {
        @Override
        synchronized public void run() {
            try {
                System.out.println("begin B ThreadName="
                        + Thread.currentThread().getName() + "  "
                        + System.currentTimeMillis());
                Thread.sleep(5000);
                System.out.println("  end B ThreadName="
                        + Thread.currentThread().getName() + "  "
                        + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    Main.java

    public class Main{
        public static void main(String[] args) {
            try {
                ThreadB b = new ThreadB();
                ThreadA a = new ThreadA(b);
                a.start();
                b.start();
                b.join(2000);
                System.out.println("    main end "
                        + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    jion方法的源代码:

    public final synchronized void join(long millis)
        throws InterruptedException {
            long base = System.currentTimeMillis();
            long now = 0;
    
            if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }
    
            if (millis == 0) {
                while (isAlive()) {
                    wait(0);
                }
            } else {
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }
        }
    

    如上的3个类,组成的这篇博文的主角。当我们执行main方法后,有几率会出现如下顺序的日志:

    • 日志1:
    begin A ThreadName=Thread-1  1545465206016
      end A ThreadName=Thread-1  1545465211018
       main end 1545465211019
    begin B ThreadName=Thread-0  1545465211020
      end B ThreadName=Thread-0  1545465216028
    

    根据该日志的打印顺序和结果来看:

    1. b.join(2000)处,jion方法拿到锁,然后在jion方法里执行到wait()时释放锁。
    2. 线程a获得锁,TheadA类的run()中的sleep(5000)处阻塞,直到run()方法执行完毕,线程a释放锁。在进入run方法2s后,b.jion()方法在wait()处被唤醒,进入激活队列等待执行。
    3. b.jion(2000)和线程b竞争锁,结果b.jion(2000)得到锁,然后执行wait()方法和面的代码,jion()方法执行完,然后释放锁。
      4.现在main线程和b线程异步执行,但是main线程的system.out.print()先于线程b的输出执行。

    1. 日志2:
    begin A ThreadName=Thread-1  1545467317710
      end A ThreadName=Thread-1  1545467322712
    begin B ThreadName=Thread-0  1545467322714
       main end 1545467322714
      end B ThreadName=Thread-0  1545467327715
    

    根据该日志的打印顺序和结果来看:

    1. b.join(2000)处,jion方法拿到锁,然后在jion方法里执行到wait()时释放锁。
    2. 线程a获得锁,TheadA类的run()中的sleep(5000)处阻塞,直到run()方法执行完毕,线程a释放锁。在进入run方法2s后,b.jion()方法在wait()处被唤醒,进入激活队列等待执行。
    3. b.jion(2000)和线程b竞争锁,结果b.jion(2000)得到锁,然后执行wait()方法和面的代码,jion()方法执行完,然后释放锁。
    4. 现在main线程和b线程异步执行,但是main线程的system.out.print()后于线程b的输出执行。

    相关文章

      网友评论

          本文标题:《java多线程编程核心技术》-----使用jion()方法时,

          本文链接:https://www.haomeiwen.com/subject/xywikqtx.html