join方法的底层原理

先说结论:

        Join可以把指定的线程加入到当前线程,为顺将两个交替执行的线程合并为顺序执行的线程。比如在线程A中调用了线程B的Join()方法,直到线程B执行完毕后,才会继续执行线程A。

        

        底层实现是基于对象的wait和notify方法来实现的。当一个线程A执行另一个线程B的join()方法时,因为join方法是synchronized关键字修饰的,所以线程A会拿到线程B的对象锁,然后在底层会执行线程B的wait方法,那么线程A就会释放锁并进入线程B的等待池中,当线程B执行完毕后,JVM底层会自动调用线程B对象的notifyAll()方法来通知所有等待该对象锁上的线程,包括线程A。这个时候线程A会重新进入就绪状态,等待获取CPU资源继续向下执行。
 

        图上的代码解析:首先创建了两个线程对象,分别是:testA1跟testA2,然后在主线程中调用了testA1的join方法,那么主线程会获取到testA1的对象锁,然后在底层会调用testA1的wait方法,这个时候主线程就会释放掉testA1的对象锁,那么就会进入阻塞状态并进入testA1的等待池,那么就没有办法执行testA2.start方法,然后就只能等待testA1线程执行完毕,testA1线程执行完毕后,会在jvm虚拟机中,调用testA1对象的notifyall方法,用来唤醒所有等待这个对象锁的线程,这个时候主线程就会被唤醒,然后执行testA2.start方法

1.示例代码:

public class test {

    public static void main(String[] args) throws InterruptedException {

        testA testA1 = new testA();
        testA testA2 = new testA();

        testA1.start();
        testA2.start();
    }

    static class testA extends Thread{

        @Override
        public void run() {

            for (int i = 0; i < 100; i++) {
                System.out.println("名称为:" + Thread.currentThread().getName() + "的线程:" + i);
            }

        }

    }
}

运行结果:

         可以看到线程是同步执行的,但如果想要等待A1线程执行完成再执行A2线程,可以使用线程的join方法

2.加join方法示例代码:

public class test {

    public static void main(String[] args) throws InterruptedException {

        testA testA1 = new testA();
        testA testA2 = new testA();

        testA1.start();
        // 在main方法中执行 testA1.join(); 所以当前线程是 主线程
        testA1.join();
        testA2.start();
    }

    static class testA extends Thread{

        @Override
        public void run() {

            for (int i = 0; i < 100; i++) {
                System.out.println("名称为:" + Thread.currentThread().getName() + "的线程:" + i);
            }

        }

    }
}

运行结果:

猜你喜欢

转载自blog.csdn.net/qq_26112725/article/details/131326689