本文不是介绍wait和join方法是什么或怎么用,而只是介绍两者的区别,具体两个函数的用法请参考相关文档。
为了说明问题,编写了以下几行代码。 package aust.hao.thread; import java.text.SimpleDateFormat; import java.util.Date; public class Demo extends Thread { public static void main(String[] args) throws Exception { // waitTest(); // for test1 // joinTest(); // for test2 } static void waitTest() throws Exception { System.out.println("-------------------- Wait Test --------------------"); Demo t1 = new Demo("t1"); show("starts"); t1.start(); show("calls t1.wait()"); synchronized (t1) { t1.wait(1); } show("continues"); } @Override public void run() { synchronized (this) { show("Enter synchronized block"); sleepms(1000); show("calls notify()"); this.notify(); sleepms(2000); show("Exit synchronized block"); } sleepms(3000); show("exits."); } private void sleepms(int ms) { try { show("sleeps " + ms + " ms."); Thread.sleep(ms); } catch (Exception e) { e.printStackTrace(); } } static void joinTest() throws Exception { System.out.println("-------------------- Join Test --------------------"); Demo t2 = new Demo("t2"); show("starts"); t2.start(); show("call t2.joins()"); t2.join(); show("continues"); } public Demo() { } public Demo(String name) { super(name); } public static void show(String msg) { SimpleDateFormat sdf = new SimpleDateFormat("[HH:mm:ss.SSS]"); System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " " + msg); } }
test1: 执行以后结果如下。 -------------------- Wait Test -------------------- [11:48:17.796] main starts [11:48:17.797] main calls t1.wait() [11:48:17.797] waitThread Enter synchronized block [11:48:17.797] waitThread sleeps 1000 ms. [11:48:18.799] waitThread calls notify() [11:48:18.799] waitThread sleeps 2000 ms. [11:48:20.799] waitThread Exit synchronized block [11:48:20.799] waitThread sleeps 3000 ms. [11:48:20.801] main continues [11:48:23.799] waitThread exits.
如果把 notify() 注释掉(即不调用notify),结果结果如下: -------------------- Wait Test -------------------- [11:49:41.063] main starts [11:49:41.064] main calls t1.wait() [11:49:41.064] waitThread Enter synchronized block [11:49:41.064] waitThread sleeps 1000 ms. [11:49:42.064] waitThread sleeps 2000 ms. [11:49:44.065] waitThread Exit synchronized block [11:49:44.065] waitThread sleeps 3000 ms. [11:49:44.066] main continues [11:49:47.065] waitThread exits.
test2: 使用join -------------------- Join Test -------------------- [11:50:26.715] main starts [11:50:26.716] main call t2.joins() [11:50:26.716] joinThread Enter synchronized block [11:50:26.716] joinThread sleeps 1000 ms. [11:50:27.718] joinThread sleeps 2000 ms. [11:50:29.718] joinThread Exit synchronized block [11:50:29.718] joinThread sleeps 3000 ms. [11:50:32.719] joinThread exits. [11:50:32.719] main continues
几点结论 wait必需要在synchronized块才起作用,而且必需是调用当前线程(main线程)和被调用线程(t1)都是才可以。join没有这个要求。
wait在调用后,可以由notify通知后提前返回主程序。而join必需等被调用线程结束后才能返回。
即使调用了notify函数,也不是立即返回,需要被调用函数执行完当前的synchronized块后才可以返回。
问题: 如果不调用notify的结果和调用的是一样的,这个如何理解?待进一步分析。