简单实现生产者和消费者模式
本实例中单独为生产者和消费者各开辟一个线程作为生产者和消费者的执行线程,在生产者消费者设计模式中存在一个数据缓冲区,使生产者和消费者的“生产”和“消费”动作都在该缓冲区进行,这样做的目的就是保证了生产者和消费者的完美解耦,试想一下如果没了这个缓冲区,生产者和消费者中的方法互调,那么两个类的关联度(耦合度)就会很高,一旦一个发生变化,势必会影响另外一个;
下面开始我们的实例:
首先是生产者的代码:
代码块11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public class Product implements Runnable{
private Queue queue;
public Product(Queue queue){ this.queue = queue; }
@Override public void run() { try{ for(int i = 0; i < 10; i++){ queue.product("Product------" + "No." + i); } }catch (Exception e){ e.printStackTrace(); } } }
|
这是消费者:
代码块21 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public class Consumer implements Runnable{
private Queue queue;
public Consumer(Queue queue){ this.queue = queue; }
@Override public void run() { try{ for(int i = 0; i < 10; i++){ System.out.println("already gone : " + queue.consumer()); } }catch (Exception e){ e.printStackTrace(); } } }
|
这是缓冲区,几乎所有的逻辑都是在这里实现的:
代码块31 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
public class Queue { private Object signal = new Object(); private boolean isFull = false; private List list = new ArrayList<>();
public void product(String msg) throws Exception{ synchronized (signal){ if(!isFull){ list.add(msg); isFull = true; System.out.println("Product One !"); signal.notify(); } signal.wait(); } }
public String consumer() throws Exception{ synchronized (signal){ if(!isFull){ System.out.println("Empty Product !"); signal.wait(); } isFull = false; signal.notify(); } String result = ""; if(list.size() > 0){ result = this.list.get(list.size() - 1); this.list.remove(list.size() - 1); } return result; } }
|
上面这个模式利用java现有的阻塞队列很容易实现,可以避免上述代码中很大一部分代码(线程的挂起、唤醒、队列弹出数据等)