2016.8.5
写这么个例子:
有一个盒子,里面只能放一个数字,
盒子空时生产者才能放入数字,
盒子满时消费者才能取出数字。
盒子
class Box {
public int boxValue=0;
}
生产者
class Producer extends Thread{
private Box box;
public Producer(Box box){
this.box=box;
}
public void run(){
for(int i=1;i<=10;i++){
synchronized(box){
while(box.boxValue!=0){
System.out.println("生产者:满了");
try {
box.wait();//线程休眠,等待唤醒,并释放box对象锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
box.boxValue=i;
System.out.println("生产者放入了数字:"+i);
box.notify();//随机唤醒一个正在等待box的线程
}
}
}
}
消费者
class Consumer extends Thread{
private Box box;
public Consumer(Box box){
this.box=box;
}
public void run(){
for(int i=1;i<=5;i++){
synchronized(box){
while(box.boxValue==0){
System.out.println("消费者:空了");
try {
box.wait();//线程休眠,等待唤醒,并释放box对象锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者取出了数字:"+box.boxValue);
box.boxValue=0;
box.notify();//随机唤醒一个正在等待box的线程
}
}
}
}
运行
public static void main(String[] args){
Box box = new Box();
Thread producer = new Producer(box);
Thread consumer = new Consumer(box);
producer.start();
consumer.start();
}
结果
搜狗截图20160805142606.png
总结
- wait()和notify()只能写在synchronized同步方法或同步块中。
- wait(),线程休眠,等待唤醒,并释放对象锁(monitor)
- notify(),随机唤醒一个正在等待对象锁的线程
- notifyAll(),唤醒所有正在等待对象锁的线程
- 若没有正在等待对象锁的线程,则notify()和notifyAll()不起作用
- 一个线程被唤醒不代表立即获取了对象的monitor,只有等调用完notify()或者notifyAll()并退出synchronized块,释放对象锁后,其余线程才可获得锁执行。
- 至于哪个线程接下来能够获取到对象的monitor就具体依赖于操作系统的调度了。