> 文档中心 > JUC中的join源码解读

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锁进行等待    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;     } }    }
//waitvoid 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锁的所有线程的操作来保证线程的执行顺序,类似于串行化

WIFI共享精灵