Java线程通信实现生产者-消费者_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java线程通信实现生产者-消费者

Java线程通信实现生产者-消费者

 2013/9/4 21:14:28  tonlion2046  程序员俱乐部  我要评论(0)
  • 摘要:生产者消费者是经典的线程之间同步通信问题,生产者线程只有在产品仓库中没有产品的时候才生产产品,当它生成完一个产品以后唤醒消费者线程,消费者线程只有在产品仓库中有产品的时候才能取走产品,然后唤醒生产者线程。Java可以有好几种方法解决这个问题。首先基础的当然是用Object的wait()、notify()和notifyAll()。产品仓库类://产品仓库publicclassProductStore{privatebooleanflag=false;publicbooleanhasProduct
  • 标签:实现 Java 消费者 线程

生产者消费者是经典的线程之间同步通信问题,生产者线程只有在产品仓库中没有产品的时候才生产产品,当它生成完一个产品以后唤醒消费者线程,消费者线程只有在产品仓库中有产品的时候才能取走产品,然后唤醒生产者线程。

Java可以有好几种方法解决这个问题。首先基础的当然是用Object的wait()、notify()和notifyAll()。

产品仓库类:

class="java" name="code">//产品仓库
public class ProductStore {
	private boolean flag =  false;
	public boolean hasProduct(){//是否有产品
		return flag;
	}
	/**
	 * 生产产品
	 * @throws Exception
	 */
	public synchronized void makeProduct() throws Exception{
		while(hasProduct()){//如果生产线程唤醒的还是生产线程,这个被唤醒的生产线程将继续wait
			this.wait();
		}
		Thread.sleep(300);
		flag = true;
		System.out.println(Thread.currentThread().getName()+":生产了一个产品");
		this.notifyAll();//唤醒所有线程
	}
	/**
	 * 取走产品
	 * @throws Exception
	 */
	public synchronized void getProduct() throws Exception{
		while(!hasProduct()){
			this.wait();
		}
		Thread.sleep(100);
		flag = false;
		System.out.println(Thread.currentThread().getName()+":取走一个产品");
		this.notifyAll();
	}
}

?生产者类:

public class Producer implements Runnable{
	
	ProductStore store;
	public Producer(ProductStore store){
		this.store = store;
	}

	@Override
	public void run() {
		try {
			store.makeProduct();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

?消费者类:

public class Consumer implements Runnable{
	
	ProductStore store;
	public Consumer(ProductStore store){
		this.store = store;
	}
	
	@Override
	public void run() {
		try {
			store.getProduct();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

?主测试类:

public class Test3 {	
	public static void main(String[] args) {
		ProductStore store = new ProductStore();
		for (int i = 1; i <= 5; i++) {
			new Thread(new Consumer(store), "消费者"+i).start();
		}
		
		for (int i = 1; i <= 5; i++) {
			new Thread(new Producer(store), "生产者"+i).start();
		}
	}
}

运行结果:

生产者1:生产了一个产品
消费者4:取走一个产品
生产者4:生产了一个产品
消费者5:取走一个产品
生产者2:生产了一个产品
消费者1:取走一个产品
生产者5:生产了一个产品
消费者2:取走一个产品
生产者3:生产了一个产品
消费者3:取走一个产品

?第二种方法就是利用java.util.concurrent包下的Lock得到Conditon,利用Condition的await()、signal()、signalAll()实现线程的通信:

产品仓库类:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//产品仓库
public class ProductStore {
	private boolean flag =  false;	
	private Lock lock = new ReentrantLock();  
	private Condition condition = lock.newCondition(); //得到condition   

	public boolean hasProduct(){//是否有产品
		return flag;
	}
	/**
	 * 生产产品
	 * @throws Exception
	 */
	public void makeProduct() throws Exception{
		lock.lock();  
		try {
			while(hasProduct()){//如果生产线程唤醒的还是生产线程,这个被唤醒的生产线程将继续wait
				condition.await();
			}
			Thread.sleep(300);
			flag = true;
			System.out.println(Thread.currentThread().getName()+":生产了一个产品");
			condition.signalAll();//唤醒所有线程
		} finally{
			lock.unlock();  
		}
	}
	/**
	 * 取走产品
	 * @throws Exception
	 */
	public void getProduct() throws Exception{
		lock.lock();  
		try {
			while(!hasProduct()){
				condition.await();
			}
			Thread.sleep(100);
			flag = false;
			System.out.println(Thread.currentThread().getName()+":取走一个产品");
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}
}

?makeProduct和getProduct方法不再使用synchronized修饰,所以使用Lock来控制同步,conditon的await()、singal()、singalAll()分别替换了Object的wait()、notify()和notifyAll()。

发表评论
用户名: 匿名