《java多线程编程核心技术》-----使用jion()方法时,代码的执行顺序总结

在读到《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()方法时,代码的执行顺序总结)