并发编程13-join

261 阅读2分钟

blog.csdn.net/chenkaibsw/…

1.概述

  • join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行

2.示例

  • thread.join();
  • thread.join(long millis); //等待millis时间后串行变成继续并行.
public class JoinThreadTest {
    public void a(Thread joinThread) {

        System.out.println("方法a执行了...");
        joinThread.start();
        try {
            joinThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("a方法执行完毕...");

    }

    public void b() {
        System.out.println("加塞线程开始执行....");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("加塞线程执行完毕...");
    }
    
    /**
    方法a执行了...
    加塞线程开始执行....
    加塞线程执行完毕...
    a方法执行完毕...
    */
     public static void main(String[] args) {
        JoinThreadTest joinThreadTest = new JoinThreadTest();
        //准备插入的线程
        Thread joinThread = new Thread(new Runnable() {

            @Override
            public void run() {
                joinThreadTest.b();
            }
        });

        //插入到线程
        new Thread(new Runnable() {

            @Override
            public void run() {
                joinThreadTest.a(joinThread);
            }
        }).start();
    }
    
    
}

3.源码

public class Thread implements Runnable {
    public final void join() throws InterruptedException {
            join(0);
        }


    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) {
            //isAlive是加塞线程,
            while (isAlive()) {
            //如果子线程存活则让当前线程wait,(wait的是synchronized的对象,而synchronized的是当前对象)
            //锁的是外层调用的的线程
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }
    
    //Tests if this thread is alive. A thread is alive if it has  been started and has not yet died.
    //也就是sleep的时候也算是活着.
    public final native boolean isAlive();
}

Thread的join方法线程有synchronized修饰,而如果synchronized获得对象锁是线程的实例时,此时比较特殊,当该线程终止的时候,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程. 

也就是如果加塞线程活着,则将当前线程wait(),当加塞线程完成之后,则会调用自身的notifyall(),然后当前线程notify继续.
因为如果synchronized获得对象锁是线程的实例时,此时比较特殊,当该线程终止的时候,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程.

4. 总结

  • join方法要放在start后面,如果放在start前,并不能起到同步的作用

参考文章:Java中的join方法原理详解