JUC中的join源码解读

1.按顺序执行

        static class MyThread implements Runnable{
            private String name;
            public MyThread(String name){
                this.name=name;
            }
            @Override
            public void run() {
                System.out.println(name + Thread.currentThread());
            }
        }

    public static void main(String[] args) throws InterruptedException {
        MyThread AThread = new MyThread("线程A");
        MyThread BThread = new MyThread("线程B");
        Thread t1 = new Thread(AThread);
        Thread t2 = new Thread(BThread);
        t1.start();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
        t1.join();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
        t2.start();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
        t2.join();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
    }

在这里插入图片描述

2.另一种按顺序执行

        static class MyThread implements Runnable{
            private String name;
            public MyThread(String name){
                this.name=name;
            }
            @Override
            public void run() {
                System.out.println(name + Thread.currentThread());
            }
        }

    public static void main(String[] args) throws InterruptedException {
        MyThread AThread = new MyThread("线程A");
        MyThread BThread = new MyThread("线程B");

        Thread t1 = new Thread(AThread);
        Thread t2 = new Thread(BThread);
        t1.start();
        t2.start();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
        t1.join();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
        t2.join();
        System.out.println(t1.getName() + t1.isAlive());
        System.out.println(t2.getName()+t2.isAlive());
    }

在这里插入图片描述

结论:调用join后,会阻塞当前线程,并且等待子线程执行完唤醒

//join源码
//上的是悲观锁synchronized,因为会进行wait等待操作,是需要持有synchronized锁才能进入等待,wait会释放锁
    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;
            }
        }
    }
//wait
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
  assert(this == JavaThread::current(),  "thread consistency check");
  ...
  // Notify waiters on thread object. This has to be done after exit() is called
  // on the thread (if the thread is the last thread in a daemon ThreadGroup the
  // group should have the destroyed bit set before waiters are notified).
  ensure_join(this); //唤醒操作
  assert(!this->has_pending_exception(), "ensure_join should have cleared");
  ...

//ensure_join(this)
static void ensure_join(JavaThread* thread) {
  // We do not need to grap the Threads_lock, since we are operating on ourself.
  Handle threadObj(thread, thread->threadObj());
  assert(threadObj.not_null(), "java thread object must exist");
  ObjectLocker lock(threadObj, thread);
  // Ignore pending exception (ThreadDeath), since we are exiting anyway
  thread->clear_pending_exception();
  // Thread is exiting. So set thread_status field in  java.lang.Thread class to TERMINATED.
  java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
  // Clear the native thread instance - this makes isAlive return false and allows the join()
  // to complete once we've done the notify_all below
  //这里是清除native线程,使活跃状态isAlive()方法返回false
  java_lang_Thread::set_thread(threadObj(), NULL);
  lock.notify_all(thread);//唤醒持有该锁的全部线程
  // Ignore pending exception (ThreadDeath), since we are exiting anyway
  thread->clear_pending_exception();
}

总结:join方法通过调用线程持有子线程悲观锁synchronized,然后进行wait操作阻塞自己,等待子线程在执行结束后,通过notifyAll操作唤醒持有子线程synchronized锁的所有线程的操作来保证线程的执行顺序,类似于串行化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值