利用BlockingQueue实现生产者消费者模式
一、BlockingQueue介绍
BlockingQueue是 java.util.concurrent 包提供的用于解决并发生产者 - 消费者问题的类。在往队列中添加或者取出元素时通过ReentrantLock实现线程安全。常见的阻塞队列有ArrayBlockingQueue (由数组支持的有界队列)、LinkedBlockingQueue (由链接节点支持的可选有界队列)、PriorityBlockingQueue (由优先级堆支持的无界优先级队列)、DelayQueue (由优先级堆支持的、基于时间的调度队列)
二、多线程生产者消费者示例
1.定义生产者者
class Producer implements Runnable {
private volatile boolean isRunning = true;
private String name;
public Producer(String name) {
this.name = name;
}
@Override
public void run() {
try {
String deviceId = "cs.001";
String subDeviceId = deviceId + COLLECTION_BOARDS2[0];
while (isRunning) {
DevImsi data = imsiBuilder.buildImsi(deviceId, subDeviceId);
if (!blockingQueue.offer(data, 2, TimeUnit.SECONDS)) {
System.out.println("failed to put data into queue: " + data);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
isRunning = false;
} finally {
System.out.println("Thread: " + this.name + " quit from producer thread");
}
}
public void stop() {
isRunning = false;
}
}
2.定义消费者
class Consumer implements Runnable {
private volatile boolean isRunning = true;
private String name;
public Consumer(String name) {
this.name = name;
}
@Override
public void run() {
try {
while (isRunning) {
DevImsi data = null;
data = blockingQueue.poll(2, TimeUnit.SECONDS);
System.out.println(data);
}
} catch (InterruptedException e) {
e.printStackTrace();
isRunning = false;
} finally {
System.out.println("Thread: " + this.name + " quit from consumer thread");
}
}
public void stop() {
isRunning = false;
}
}
3.测试
public static void main(String[] args) throws InterruptedException {
Producer producer1 = new Producer("producer1");
Producer producer2= new Producer("producer2");
Producer producer3= new Producer("producer3");
Consumer consumer1 = new Consumer("consumer1");
Consumer consumer2 = new Consumer("consumer2");
ExecutorService service = Executors.newCachedThreadPool();
service.execute(producer1);
service.execute(producer2);
service.execute(producer3);
service.execute(consumer1);
service.execute(consumer2);
TimeUnit.SECONDS.sleep(3);
producer1.stop(); // 一定要先关闭生产者
producer2.stop();
producer3.stop();
consumer1.stop();
consumer2.stop();
TimeUnit.SECONDS.sleep(2);
service.shutdown();
}