java中当线程终止时,会调用自身的notifyAll方法的原理分析

例子代码

public class Client {

  public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(() -> {
      System.out.println(Thread.currentThread().getName() + " run start");
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " run end");
    });
    thread.start();
    thread.join();
    System.out.println(Thread.currentThread().getName() + " run end");
  }

}

主要是关于Thread.join()方法的用法,join()方法内部也是调用的wait()方法,
将当前线程也就是main线程阻塞住,但在这个过程没有调用notify()和notifyAll()方法,
那main线程是什么时候被唤醒的呢?

原理

这里使用openjdk16的源码,其实各版本差别不大,github地址
主要源码都在 src/hotspot/share/runtime/thread.cpp 文件中

void Thread::call_run() {
  ...
  this->pre_run();
  this->run();
  this->post_run();
  ...
}

void JavaThread::post_run() {
  this->exit(false);
  ...
}

void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
  ...
  ensure_join(this);
  ... 
}

static void ensure_join(JavaThread* thread) {
  ...
  lock.notify_all(thread);
  ...
}

可以看到在线程执行结束前会调用notifyAll()方法,唤醒所有等待的线程,示例代码中的main线程就是这样被唤醒的。

参考

《Java并发编程的艺术》中关于“当线程终止时,会调用自身的notifyAll方法”?何以见得?

posted @ 2022-03-14 19:57  strongmore  阅读(558)  评论(0编辑  收藏  举报