生产者-消费者模式为多线程之间协作提供了良好的解决方案,一般有2类线程,生产者类线程提交用户请求,消费者类线程则负责处理生产者线程提交的请求。
生产者-消费者模式架构图:
由图可见,生产者线程和消费者线程并不直接通信,内存缓存区充当二者的桥梁,将生产者线程和消费者线程解耦。同时由于内存缓存区的存在,也缓解了生产者和消费者之间的速度差异,从而一定程度上缓解了由于性能瓶颈对系统性能的影响。
代码示例:
PCData类:
public final class PCData {
private final int intData;
public PCData(int d){
intData = d;
}
public PCData(String d){
intData = Integer.valueOf(d);
}
public int getData(){
return intData;
}
public String toString(){
return "data="+intData;
}
}
生产者线程:
public class Producer implements Runnable {
private volatile boolean isRunning = true;
private BlockingQueue<PCData> queue;
private static AtomicInteger count = new AtomicInteger();
private static final int SLEEPTIME = 1000;
public Producer(BlockingQueue<PCData> queue){
this.queue = queue;
}
public void run(){
PCData data = null;
Random r = new Random();
System.out.println("start producer id = "+Thread.currentThread().getId());
try{
while(isRunning){
Thread.sleep(r.nextInt(SLEEPTIME));
data = new PCData(count.incrementAndGet());
System.out.println(data + " is put to queue");
if(!queue.offer(data,2, TimeUnit.SECONDS)){
System.out.println("failed to put data :"+data);
}
}
}catch (InterruptedException e){
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void stop(){
isRunning = false;
}
}
消费者线程:
public class Consumer implements Runnable {
private BlockingQueue<PCData> queue;
private static final int SLEEPTIME = 1000;
public Consumer(BlockingQueue<PCData> queue){
this.queue = queue;
}
public void run(){
System.out.println("start consumer id = " + Thread.currentThread().getId());
Random r = new Random();
try{
while(true) {
PCData data = queue.take();
if (data != null) {
int re = data.getData() * data.getData();
System.out.println(MessageFormat.format("{0}*{1}={2}", data.getData(), data.getData(), re));
Thread.sleep(r.nextInt(SLEEPTIME));
}
}
}catch(InterruptedException e){
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
测试类:
public class Main {
public static void main(String[] args) throws Exception{
BlockingQueue<PCData> queue = new LinkedBlockingDeque<PCData>(10);
Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);
Producer producer3 = new Producer(queue);
Consumer consumer1 = new Consumer(queue);
Consumer consumer2 = new Consumer(queue);
Consumer consumer3 = new Consumer(queue);
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(producer1);
executor.execute(producer2);
executor.execute(producer3);
executor.execute(consumer1);
executor.execute(consumer2);
executor.execute(consumer3);
Thread.sleep(10 * 1000);
producer1.stop();
producer2.stop();
producer3.stop();
Thread.sleep(3000);
executor.shutdown();
}
}
测试类创建了3个生产者线程和3个消费者线程,LinkedBlockingDeque充当内存缓冲区的角色,两类线程都启动并运行起来后,在Thread.sleep(10 * 1000);时间内,生产者线程不停的往内存缓存中中提交数据,消费者线程不停的从内存缓冲区中取出数据并处理,Producer和Consumer类并不直接打交道,他们只同LinkedBlockingDeque打交道。
《Java性能优化》 葛一鸣
多线程模式之生产者-消费者模式
猜你喜欢
转载自frank1234.iteye.com/blog/2173259
今日推荐
周排行