Java Executor框架就是实现了生产者消费者模式,分别负责添加任务到阻塞队列里和执行任务。而之前经典的方法是基于wait和notify方法实现生产者和消费者合作的,在队列满了或者是空的条件下将阻塞。
它的确是一种实用的设计模式,常用于编写多线程或并发代码。下面是它的一些优点:
- 它简化的开发,你可以独立地或并发的编写消费者和生产者,它仅仅只需知道共享对象是谁
- 生产者不需要知道谁是消费者或者有多少消费者,对消费者来说也是一样
- 生产者和消费者可以以不同的速度执行
- 分离的消费者和生产者在功能上能写出更简洁、可读、易维护的代码
1. 阻塞队列接口,ArrayBlockingQueue和LinkedBlockingQueue, PriorityBlockingQueue实现了BlockingQueue接口。
public interface BlockingQueue<E> extends Queue<E> {
boolean add(E e);
boolean offer(E e);
void put(E e) throws InterruptedException;//如果满了,将阻塞
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
E take() throws InterruptedException;//如果空了,将阻塞
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
int remainingCapacity();
boolean remove(Object o);
public boolean contains(Object o);
int drainTo(Collection<? super E> c);
int drainTo(Collection<? super E> c, int maxElements);
}
2. 外部类的实现方式,生产者消费者例程,生产者生产10个数据,消费者消费10个数据,也可以添加业务逻辑
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
public class producerConsumer {
public static void main(String[] args) {
// TODO Auto-generated method stub
BlockingQueue sharedQueue=new LinkedBlockingQueue();//共享域
Thread producer=new Thread(new Producer(sharedQueue)); //建立线程的方式
Thread consumer=new Thread(new Consumer(sharedQueue));
producer.start();//启动线程
consumer.start();
}
}
class Producer implements Runnable{
private final BlockingQueue sharedQueue;
public Producer(BlockingQueue sharedQueue){
this.sharedQueue=sharedQueue;
}
public void run(){
for(int i=0;i<10;i++){
try{System.out.println("Producer "+ i);
sharedQueue.put(i);
}
catch(InterruptedException e){
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
}
class Consumer implements Runnable{
private final BlockingQueue sharedQueue;
public Consumer(BlockingQueue sharedQueue){
this.sharedQueue=sharedQueue;
}
public void run(){
while(true){
try{
System.out.println("Consumer: "+sharedQueue.take());
}
catch(InterruptedException e){
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
}
3.内部类的实现方式,生产者消费者模式,注意和外部类的区别,很有趣
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
public class producerConsumer {
public static void main(String[] args) {
// TODO Auto-generated method stub
BlockingQueue sharedQueue=new LinkedBlockingQueue();
producerConsumer producerConsumer=new producerConsumer();
Thread producer=new Thread(producerConsumer.new Producer(sharedQueue));
Thread consumer=new Thread(producerConsumer.new Consumer(sharedQueue));
producer.start();
consumer.start();
}
class Producer implements Runnable{
private final BlockingQueue sharedQueue;
public Producer(BlockingQueue sharedQueue){
this.sharedQueue=sharedQueue;
}
public void run(){
for(int i=0;i<10;i++){
try{System.out.println("Producer "+ i);
sharedQueue.put(i);
}
catch(InterruptedException e){
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
}
class Consumer implements Runnable{
private final BlockingQueue sharedQueue;
public Consumer(BlockingQueue sharedQueue){
this.sharedQueue=sharedQueue;
}
public void run(){
while(true){
try{
System.out.println("Consumer: "+sharedQueue.take());
}
catch(InterruptedException e){
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
}
}