wait玩法
看个小例子:
package demo.thread.wait;
/**
* 共享对象(鱼篓)
*/
public class Well {
public int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
package demo.thread.wait;
/**
* 生产者(钓鱼)
*/
public class Producer implements Runnable{
// 假设鱼篓的最大容量是3条鱼
public static int MAX_FISH_COUNT = 3;
// 线程调用的共享对象
public Well f;
public Producer(Well f) {
this.f = f;
}
@Override
public void run() {
while (true) {
// 获取共享对象监视器锁
synchronized (f) {
// 达到最大容量停止钓鱼(停止生产)
while (f.getCount() == MAX_FISH_COUNT) {
try {
System.out.println(Thread.currentThread().getName() + "已经达到最大容量,停止钓鱼");
f.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 未达到最大容量,继续钓鱼
f.count ++;
System.out.println(Thread.currentThread().getName() + "钓了第" + f.count + "条鱼");
// 唤醒所有调用该共享对象的线程
f.notifyAll();
}
}
}
}
package demo.thread.wait;
/**
* 消费者(吃鱼)
*/
public class Consumer implements Runnable{
public Well f;
public Consumer(Well f) {
this.f =f;
}
@Override
public void run() {
while (true) {
// 获取共享对象监视器锁
synchronized (f) {
while (f.count == 0) {
try {
System.out.println(Thread.currentThread().getName() + "没有鱼了,停止吃鱼");
f.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 开始吃鱼
System.out.println(Thread.currentThread().getName() + "开始吃第" + f.count + "条鱼");
f.count --;
f.notifyAll();
}
}
}
}
package demo.thread.wait;
public class WaitTest {
public static void main(String[] args) {
// 新建线程共享对象
Well f = new Well();
Producer p = new Producer(f);
Consumer c1 = new Consumer(f);
Consumer c2 = new Consumer(f);
Consumer c3 = new Consumer(f);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c1);
Thread t3 = new Thread(c2);
Thread t4 = new Thread(c3);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
测试结果如下
从测试的结果可以看出:
1.对象在调用了wait之后就释放了自身的锁,其他线程可以参与调用。
2.在执行过程中调用了notifyAll方法后,会唤醒所有调用该对象的线程(并不是一定等鱼娄中的鱼满了才开始吃鱼的)将鱼篓的容量调大些就能看出了。