生产者消费者模式是一个经典的多线程设计模式,它为多线程间的协作提供了良好的解决方案。在生产者消费者模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程。生产者线程足额提交用户请求,消费者线程负责具体处理生产者提交的任务。生产者和消费者之间则通过共享内存缓冲区进行通信。
如图:
例子:
生产者
import java.util.concurrent.BlockingQueue;
class Producer implements Runnable {
private String name;
BlockingQueue<Product> s;
public Producer(String name, BlockingQueue<Product> s) {
this.name = name;
this.s = s;
}
public void run() {
try {
while (true) {
Product product = new Product((int) (Math.random() * 10000)); // 产生0~9999随机整数
System.out.println(name + "准备生产(" + product.toString() + ").");
s.put(product);
System.out.println(name + "已生产(" + product.toString() + ").");
System.out.println("===============");
Thread.sleep(500);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
消费者
/**
* Created by niehongtao on 16/7/14.
*/
import java.util.concurrent.BlockingQueue;
class Consumer implements Runnable {
private String name;
BlockingQueue<Product> s;
public Consumer(String name, BlockingQueue<Product> s) {
this.name = name;
this.s = s;
}
public void run() {
try {
while (true) {
System.out.println(name + "准备消费产品.");
Product product = s.take();
System.out.println(name + "已消费(" + product.toString() + ").");
System.out.println("===============");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
共享数据类型
/**
* Created by niehongtao on 16/7/14.
*/
public class Product {
private int id;
public Product(int id) {
this.id = id;
}
public String toString() {// 重写toString方法
return "产品:" + this.id;
}
}
客户端
/**
* Created by niehongtao on 16/7/14.
*/
public class ProducerConsumer {
public static void main(String[] args) {
BlockingQueue<Product> queues = new LinkedBlockingQueue<Product>(10);
ExecutorService service = Executors.newCachedThreadPool();
Producer p = new Producer("张三", queues);
Producer p2 = new Producer("李四", queues);
Consumer c = new Consumer("王五", queues);
Consumer c2 = new Consumer("老刘", queues);
Consumer c3 = new Consumer("老林", queues);
service.submit(p);
service.submit(p2);
service.submit(c);
service.submit(c2);
service.submit(c3);
}
}