生产者消费者的三种实现方式

1.使用阻塞队列实现

Producer:

package 使用阻塞队列实现;

import java.util.concurrent.BlockingQueue;

//生产者
public class Producer implements Runnable{

	private BlockingQueue sharedQueue;
	//构造函数,指定生产者生产的线程要放到哪里
	public Producer(BlockingQueue sharedQueue){
		this.sharedQueue=sharedQueue;
	}
	
	public void run() {
		for(int i=0;i<10;i++){
			System.out.println("Producer:"+i); //生产者i生产
			try {
				sharedQueue.put(i);  //然后把生产的i放进阻塞队列
			} catch (InterruptedException e){
				e.printStackTrace();
			}
		}
	}
}

Consumer:

package 使用阻塞队列实现;

import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable{
	private BlockingQueue sharedQueue; //维护一个阻塞队列

	public Consumer(BlockingQueue sharedQueue){
		this.sharedQueue=sharedQueue;
	}
	@Override
	public void run() {
		while(true){
			try {
				int i = (Integer)sharedQueue.take();
				System.out.println("Consumer:"+i);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
	}
}

ProducerConsumerPattern:

package 使用阻塞队列实现;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumerPattern {
	public static void main(String[] args){
		BlockingQueue sharedQueue=new LinkedBlockingQueue();
		Thread producer=new Thread(new Producer(sharedQueue));
		Thread consumer=new Thread(new Consumer(sharedQueue));
		producer.start();
		consumer.start();
	}
}

2.使用Object的wait(),notify()实现

package 使用Object的wait_notify方法来实现;

import java.util.PriorityQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class ProducerConsumerPattern {
	PriorityBlockingQueue queue=new PriorityBlockingQueue<Integer>();
	class Producer implements Runnable{
		@Override
		public void run() {
			while(true){
				synchronized (queue) {
					while(queue.size()==10){//如果队列满了的话就阻塞
						try {
							queue.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							queue.notify();
						}
					}
					queue.offer(1);
					queue.notify();
				}
			}
		}
	}
	
	class Consumer implements Runnable{
		
		@Override
		public void run() {
			while(true){
				synchronized (queue) {
					while(queue.size()==0){ //在队列为空的情况下阻塞
						try {
							queue.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							queue.notify();
						}
					}
					queue.poll();
					queue.notify();
				}
			}
		}
	}
}

3.使用Condition实现

    任何一个Java对象,都拥有一组监视器方法,主要包括wait(),wait(long timeout),notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式。

    Condition对象是由Lock对象创建出来的。

Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();

实现如下:

package 使用Condition实现;

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

public class 使用Condition实现 {
	private PriorityBlockingQueue<Integer> queue=new PriorityBlockingQueue<>(10);
	private Lock lock=new ReentrantLock();
	private Condition notFull=lock.newCondition();
	private Condition notEmpty=lock.newCondition();
	
	class Producer extends Thread{

		@Override
		public void run() {
			while(true){
				lock.lock();
				try{
					while(queue.size()==10){
						try {
							notFull.await();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					queue.offer(1);   //因为放进去了一个所以不空了
					notEmpty.signal(); //唤醒一个等待在condition上的线程
				}finally{
					lock.unlock();
				}
				
			}
		}
	}
	class Consumer extends Thread{
		public void run(){
			while(true){
				lock.lock();
				try{
					while(queue.size()==0){
						try {
							notEmpty.await();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					queue.poll();
					notFull.signal();
				}finally{
					lock.unlock();
				}
			}
		}
	}

}

猜你喜欢

转载自blog.csdn.net/hellodake/article/details/82011865