经典生存者消费者模型,使用Object的wait,notify和notifyAll实现
调用wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。
调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
调用notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
/****************************************************************************************
Copyright © 2014 Your Company/Org. All rights reserved.<br>
Reproduction or transmission in whole or in part, in any form or<br>
by any means, electronic, mechanical or otherwise, is prohibited<br>
without the prior written consent of the copyright owner. <br>
****************************************************************************************/
package com.beston.concurrency.synchronization;
/**
* @ClassName: WaitNotify
* @Description: 经典生存者消费者模型,使用Object的wait,notify和notifyAll实现
* @author beston
* @date 2014年3月28日 上午10:11:10
* @version v1.0
*
*/
public class WaitNotify {
public static void main(String[] a){
Target t = new Target();
ProduceThread p = new ProduceThread(t);
ConsumeThread c = new ConsumeThread(t);
Thread t1 = new Thread(p,"生产线程1");
Thread t2 = new Thread(p,"生产线程2");
Thread t3 = new Thread(c,"消费线程1");
Thread t4 = new Thread(c,"消费线程2");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Target{
public int i = 0;
public synchronized void produce(){
if(i == 4){
try {
System.out.println(Thread.currentThread().getName()+":生产满了,等待消费操作");
this.wait();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
i++;
this.notifyAll();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
public synchronized void consume(){
if(i == 0){
try {
System.out.println(Thread.currentThread().getName()+":消费完了,等待生产操作");
this.wait();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
i--;
this.notifyAll();
}
System.out.println(Thread.currentThread().getName()+":"+i);
this.notifyAll();
}
}
class ProduceThread implements Runnable{
private Target t;
public ProduceThread(Target t){
this.t = t;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
for(int i=0;i<20;i++){
t.produce();
try {
Thread.sleep((long) (Math.random()*50));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class ConsumeThread implements Runnable{
private Target t;
public ConsumeThread(Target t){
this.t = t;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
for(int i=0;i<20;i++){
t.consume();
try {
Thread.sleep((long) (Math.random()*50));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
结果:
生产线程1:1
消费线程1:0
生产线程2:1
消费线程2:0
生产线程2:1
消费线程2:0
消费线程1:消费完了,等待生产操作
生产线程2:1
消费线程1:1
生产线程1:2
生产线程1:3
生产线程1:4
消费线程2:3
生产线程1:4
生产线程2:生产满了,等待消费操作
消费线程2:3
生产线程2:3
消费线程1:2
生产线程2:3
消费线程2:2
消费线程2:1
消费线程1:0
生产线程1:1
消费线程1:0
生产线程2:1
消费线程1:0
消费线程2:消费完了,等待生产操作
生产线程2:1
生产线程1:2
消费线程1:1
消费线程2:1
生产线程2:2
消费线程2:1
消费线程1:0
生产线程1:1
生产线程1:2
生产线程2:3
消费线程1:2
消费线程2:1
消费线程1:0
生产线程1:1
生产线程1:2
消费线程1:1
生产线程2:2
消费线程2:1
消费线程1:0
消费线程2:消费完了,等待生产操作
生产线程1:1
消费线程2:1
生产线程2:2
消费线程2:1
生产线程1:2
生产线程1:3
生产线程1:4
消费线程1:3
消费线程1:2
生产线程2:3
消费线程2:2
生产线程1:3
消费线程1:2
生产线程1:3
生产线程2:4
消费线程2:3
生产线程1:4
消费线程1:3
生产线程1:4
生产线程2:生产满了,等待消费操作
生产线程1:生产满了,等待消费操作
消费线程2:3
生产线程1:3
生产线程2:3
生产线程2:4
生产线程2:生产满了,等待消费操作
消费线程1:3
生产线程2:3
消费线程2:2
消费线程1:1
消费线程2:0
生产线程2:1
消费线程1:0
消费线程2:消费完了,等待生产操作
消费线程1:消费完了,等待生产操作
生产线程2:1
消费线程1:1
消费线程2:1
生产线程2:2
消费线程2:1
生产线程2:2
消费线程2:1