join()方法的源码分析

/*
和主线程竞争
 */
public class Test04 {
    static int ticket = 100;
    public static void main(String[] args) {
        new Thread(()->{
            while(ticket>0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (Test04.class) {

                    System.out.println("子线程:" + ticket--);
                }
            }
        }).start();
        while(ticket>0){
            try {
                Thread.sleep(10);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (Test04.class) {

                System.out.println("主线程:" + ticket--);
            }
        }
    }
}

这个是没有使用join方法,正常竞争。

 使用thread.join()

 我们需要注意的时,在我们调用thread.join(0方法时,此时已经切换到主线程了,并不是在子线程中执行,在子线程中执行的只有run()方法

如果简单理解,那么就是在主线程中调用了thread.join(0方法,这个方法有一个判断:如果当前线程(这里指的是实例对象,就是synchronized表示的this对象thread)存活,那么join()方法,也就是在主线程中调用的join()方法会调用thread.wait()方法进入阻塞状态,导致主线程也会进入阻塞状态

如下图:子线程thread.wait()并不会影响子线程的执行,但是却会导致自身方法进入阻塞,直到子线程结束,才会跳出while循环,执行主线程,同理我们在其他线程中调用某个线程的thread.join()方法也会导致自身线程进入阻塞

 

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

猜你喜欢

转载自www.cnblogs.com/guosai1500581464/p/13394784.html
今日推荐