java多线程实现生产者和消费者

首先创建生产者和消费者工厂类

Object lock = new Object();
	boolean flag = false;
	int count = 0;
	/**
	 * 生产者
	 * @throws InterruptedException 
	 */
	public void product() throws InterruptedException{
		synchronized(lock){
			if(!flag){
				System.out.println("生产者生产的第"+count+"个");
				flag = true;
				lock.notify();
			} else {
				lock.wait();
			}
		}
	}
	
	/**
	 * 消费者
	 * @throws InterruptedException
	 */
	public void consume() throws InterruptedException{
		synchronized(lock){
			if(flag){
				System.out.println("消费者消费的第"+count+"个");
				count++;
				flag = false;
				lock.notify();
			} else {
				lock.wait();
			}
			
		}
	}

创建 生产者和消费者的多线程类

private ThreadFactory threadFactory;

	public ProductThread(ThreadFactory threadFactory) {
		super();
		this.threadFactory = threadFactory;
	}
	
	
	public void run(){
		try {
			while(true){
				threadFactory.product();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
private ThreadFactory threadFactory;

	public ConsumeThread(ThreadFactory threadFactory) {
		super();
		this.threadFactory = threadFactory;
	}

	public void run(){
		try {
			while(true){
				threadFactory.consume();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 测试类

public class Test {

	public static void main(String[] args) {
		ThreadFactory threadFactory = new ThreadFactory();
		
		ProductThread productThread = new ProductThread(threadFactory);
		productThread.start();
		
		ConsumeThread consumeThread = new ConsumeThread(threadFactory);
		consumeThread.start();
	}
	
}

控制台的打印结果,可以发现每当生产者生成一个消费者消费一个。

 如果有多个生产者和消费者呢?

改造代码

public static void main(String[] args) {
		ThreadFactory threadFactory = new ThreadFactory();
		
		ProductThread productThread = new ProductThread(threadFactory);
		productThread.start();
		
		ProductThread productThread1 = new ProductThread(threadFactory);
		productThread1.start();
		
		ConsumeThread consumeThread = new ConsumeThread(threadFactory);
		consumeThread.start();
		
		ConsumeThread consumeThread1 = new ConsumeThread(threadFactory);
		consumeThread1.start();
	}

打印结果

会发现生产者生产3后,线程没有执行了。这是为什么呢?看代码

 当生产者生产完3后,将flag置为true,然后notify(),此时会唤醒一个线程,所以就会出现一个生产者和两个消费者竞争.当生产者获取的CPU使用权后,会进入product方法,但是由于flag= true,则直接进入lock.wait();所以我们希望当唤醒线程时,只唤醒消费者的线程。

Condition关键字

condition的介绍这里就不解释了,网上相关的知识特别多。简而言之就是它可以特定的唤醒线程,而不是像notify一样全部唤醒

condition需要借助Lock来实现,它的await(),signal(),signalAll()相当于wait(),notify(),notifyAll()。

public class ThreadFactory {

	//Object lock = new Object();
	
	boolean flag = false;
	int count = 0;
	
	Lock lock = new ReentrantLock();
	
	Condition productCondition = lock.newCondition();
	
	Condition consumeCondition = lock.newCondition();
	/**
	 * 生产者
	 * @throws InterruptedException 
	 */
	public void product() throws InterruptedException{
		lock.lock();
		try {
			if(!flag){
				System.out.println("生产者生产的第"+count+"个");
				flag = true;
				consumeCondition.signal();
			} else {
				productCondition.await();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
		
	}
	
	/**
	 * 消费者
	 * @throws InterruptedException
	 */
	public void consume() throws InterruptedException{
		lock.lock();
		try {
			if(flag){
				System.out.println("消费者消费的第"+count+"个");
				count++;
				flag = false;
				productCondition.signal();
			} else {
				consumeCondition.await();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

这样一来,在生产者里面唤醒的是消费者,而在消费者里面唤醒生产者。

猜你喜欢

转载自blog.csdn.net/java_chegnxuyuan/article/details/90064570