Java多线程之 wait 和 join 的区别

本文不是介绍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

几点结论:

  1. wait必须在synchronized块才起作用,而且必须是调用当前线程(main线程)和被调用线程(t1)才可以。join没有这个要求。
  2. wait在调用后,可以由notify通知后提前返回主程序。而join必须等被调用线程结束后才能返回。
  3. 即使调用了notify函数,也不是立即返回,需要被调用函数执行完当前的synchronized块后才可以返回。

问题:

  • 如果不调用notify的结果和调用的是一样的,这个如何理解?待进一步分析。

你可能感兴趣的:(并行计算,Java程序设计,多线程,wait,notify,join,Java)