java多线程3:wait、notify和notifyAll

wait、notify和notifyAll

首先,这些方法属于Object,而不属于Thread。其次,obj.wait()、obj.notify()必须要与synchronized(obj)一起使用,也就是说obj.wait()、obj.notify()必须存在于synchronized(obj){…}的代码块内,负责就会抛出java.lang.IllegalMonitorStateException异常。一下是对这几种方法的简要介绍:

1.如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态(wait()与sleep()区别:wait()释放了锁,sleep()没有)。

2.如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。

3.如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

注:wait()有3种调用方式:wait()、wait(long timeout)、wait(long timeout, int nanos)

public class ThreadTest {

	public static void main(String[] args) {
		final PrintClass pc = new PrintClass();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				pc.ptintText("Thread-1");
			}
		});
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				pc.ptintText("Thread-2");
			}
		});
		t1.start();
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		t2.start();
	}

}

class PrintClass {

	public void ptintText(String text) {
		synchronized (this) {
			for (int i = 0; i < 15; i++) {
				try {
					System.out.println(text + ",count" + i);
					if ("Thread-1".equals(text) && i == 5) {
						this.wait();
					}
					if ("Thread-2".equals(text) && i == 9) {
						this.notify();
						this.wait();
					}
					if ("Thread-1".equals(text) && i == 14) {
						this.notify();
					}
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

线程1从0数到5交给线程2,线程2从0数到9再交给线程1,线程1从6数到14再交给线程2,线程2从10数到14,结束。

具体过程是:当线程1数到5时,调用wait()释放了当前的锁,交给了线程2并自己等待。当线程2数到9时,调用notify()激活了某一个等待的线程(这里等待的线程只有线程1,所以只能激活他),并且自己释放了锁,交给另一个线程(只能交给线程1,因为只有他)。然后线程1接着数到14,交给线程2,线程2数完。

在synchronized也可以使用这些方法:

class PrintClass {

	public synchronized void ptintText(String text) {
		for (int i = 0; i < 15; i++) {
			try {
				System.out.println(text + ",count" + i);
				if ("Thread-1".equals(text) && i == 5) {
					wait();
				}
				if ("Thread-2".equals(text) && i == 9) {
					notify();
					wait();
				}
				if ("Thread-1".equals(text) && i == 14) {
					notify();
				}
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}
}

将打印类改成这样,与前面的demo效果相同,也是用this这个类实例来同步的。

1 Reply to “java多线程3:wait、notify和notifyAll”

发表评论