Java并发:wait()、notify()、notifyAll()实现生产者-消费者模式

Java中根类 Object中 wait()、notify()、notifyAll() 三个方法都是native修饰的方法。 每个对象都有相对应的方法,使用这三种方法的前提是,正在运行的线程必须拥有该对象的锁,即在synchronized(){}中。

 

wait():当前线程放弃该对象的锁,线程处于休眠状态,直到notify()或者notifyAll()之后,才有可能继续执行。

notify():唤醒某个放弃该对象锁的线程。

notifyAll():唤醒全部放弃该对象锁的线程。

 

 

 

注意:wait() 和sleep() 两者的共同点都是使当前线程放弃CPU控制权,线程处于挂起状态,但是wait()方法会放弃synchronized块中对象的锁,但是sleep()方法却不会释放掉synchronized块中对象的锁。sleep()方法是Thread对象中的方法, wait()方法是每个对象都有的。

 

 

下面是一个比较经典的生产者-消费者模式的多线程例子:

 

 

 

package thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author:zyy
 * @名称: 生产者-消费者
 * 
 */
public class ProduceAndConsumer {
	public static void main(String[] args) {
		Product pro = new Product();
		Thread thread1 = new Thread(new Produce(pro),"thread1");
		Thread thread2 = new Thread(new Consumer(pro),"thread2");
		Thread thread3 = new Thread(new Produce(pro),"thread3");
		Thread thread4 = new Thread(new Consumer(pro),"thread4");
		ExecutorService servicePool = Executors.newCachedThreadPool();
		
		servicePool.execute(thread1);
		servicePool.execute(thread2);
		servicePool.execute(thread3);
		servicePool.execute(thread4);
//		
//		thread1.start();
//		thread2.start();
//		thread3.start();
//		thread4.start();		
//		
		
	}
}


class Product {
	
	private int size ;  //当前容量
	
	private int MAX_SIZE = 10;  //最大容量
	
	/**
	 * 消费
	 */
	public synchronized void get(){
		while(size<=0){
			System.out.println("没有商品,为空");
			try {
				this.wait();  //当没有东西可以消费的话,当前线程放弃Product对象的锁,直到有别的线程唤醒该对象锁
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "  --");
		}
		
		System.out.println("开始消费  --" + size--);
		//消费了之后,就唤醒之前放弃该对象锁的线程,(注意: 虽然notify()唤醒了,但是必须要等到该synchronized内的代码块执行完毕)
		this.notify();  
	}
	
	/**
	 * 生产
	 */
	public synchronized void add(){
		while(size>=MAX_SIZE){
			System.out.println("商品已经满了,不能存放");
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("开始生产 --" + size++);  
		this.notify(); //生产了,然后之前放弃该对象锁的线程
	}
	
}

class Produce implements Runnable{

	private Product product;

	public Produce(Product product) {
		super();
		this.product = product;
	}

	@Override
	public void run() {
		while(true){
			product.add();
		/*	try {
				TimeUnit.SECONDS.sleep(1);  //这里设置时间,可以更直观的观看消费的情况
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}*/
		}
	}
	
}


class Consumer implements Runnable{

	private Product product;

	public Consumer(Product product) {
		super();
		this.product = product;
	}
	
	@Override
	public void run() {
		while(true){
			product.get();	
//			try {
//				TimeUnit.SECONDS.sleep(2);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
		}
	}
	
}

 

 

如有不正确,欢迎拍砖!

猜你喜欢

转载自ihenu.iteye.com/blog/2286213
今日推荐