Using the notifyAll and wait Methods

Let抯 investigate how the code in CubbyHoleput and get methods helps the Producer and the Consumer coordinate their activities. The CubbyHole stores its value in a private member variable called contents. CubbyHole has another private member variable, available, that is a boolean. The available variable is true when the value has been put but not yet gotten and is false when the value has been gotten but not yet put. Here抯 one possible implementation for the put and get methods:
public synchronized int get() {    //won抰 work!
	if (available == true) {
		available = false;
		return contents;
	}
}
public synchronized int put(int value) {    //won抰 work!
	if (available == false) {
		available = true;
		contents = value;
	}
}
As implemented, these two methods won抰 work. Look at the get method. What happens if the Producer hasn抰 put anything in the CubbyHole and available isn抰 true? The get method does nothing. Similarly, if the Producer calls put before the Consumer got the value, put doesn抰 do anything.

You really want the Consumer to wait until the Producer puts something in the CubbyHole and the Producer to notify the Consumer when it抯 done so. Similarly, the Producer should wait until the Consumer takes a value (and notifies the Producer of its activities) before replacing it with a new value. The two threads must coordinate more fully and can use Objectwait and notifyAll methods to do so.

Here are the new get and put implementations that wait on and notify each other of their activities:

public synchronized int get() {
	while (available == false) {
		try {
			//wait for Producer to put value
			wait();
		} catch (InterruptedException e) { }
	}
	available = false;
	//notify Producer that value has been retrieved
	notifyAll();
	return contents;
}

public synchronized void put(int value) {
	while (available == true) {
		try {
			//wait for Consumer to get value
			wait();
		} catch (InterruptedException e) { }
	}
	contents = value;
	available = true;
	//notify Consumer that value has been set
	notifyAll();
}
The code in the get method loops until the Producer has produced a new value. Each time through the loop, get calls the wait method. The wait method relinquishes the lock held by the Consumer on the CubbyHole (thereby allowing the Producer to get the lock and update the CubbyHole) and then waits for notification from the Producer. When Producer puts something in the CubbyHole, it notifies Consumer by calling notifyAll. The Consumer then comes out of the wait state and the get method returns the value in the CubbyHole.

The put method works in a similar fashion. It waits for the Consumer thread to consume the current value before allowing the Producer to produce a new one.

The notifyAll method wakes up all threads waiting on the object in question (in this case, the CubbyHole). The awakened threads compete for the lock. One thread gets it, and the others go back to waiting. The Object class also defines the notify method, which arbitrarily wakes up one of the threads waiting on this object.

There are the three versions of the wait method contained in the Object class:

wait()
Waits indefinitely for notification. (This method was used in the producer-consumer example.)

wait(long timeout)
Waits for notification or until the timeout period has elapsed. timeout is measured in milliseconds.

wait(long timeout, int nanos)
Waits for notification or until timeout milliseconds plus nanos nanoseconds have elapsed.

Note:  Besides using these timed wait methods to synchronize threads, you also can use them in place of sleep. Both wait and sleep delay for the requested amount of time. You can easily wake up wait with a notify but a sleeping thread cannot be awakened prematurely. This doesn't matter too much for threads that don't sleep for long, but it could be important for threads that sleep for minutes at a time.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值