生产者线程负责提交用户请求,消费者线程负责具体处理生产者提交的任务,生产者和消费者之间通过共享内存缓冲区进行通信,生产者-消费者模式的核心组件是共享内存缓冲区,他作为生产者和消费者之间通信的桥梁,避免了生产者和消费者的直接通信,从而将生产者和消费者进行解耦,由于内存缓冲区的存储,允许生产者和消费者在执行速度上存在时间差。
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
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 into queue");
if (!queue.offer(data, 2, TimeUnit.SECONDS)) {
System.err.println("failed to put data:" + data);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void stop() {
isRunning = false;
}
}
import java.text.MessageFormat;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
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 (null != data) {
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 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;
}
@Override
public String toString(){
return "data:"+intData;
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<PCData> queue = new LinkedBlockingQueue<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 service = Executors.newCachedThreadPool();
service.execute(producer1);
service.execute(producer2);
service.execute(producer3);
service.execute(consumer1);
service.execute(consumer2);
service.execute(consumer3);
Thread.sleep(5 * 1000);
producer1.stop();
producer2.stop();
producer3.stop();
Thread.sleep(3000);
service.shutdown();
}
}
输出结果
start producer id=11
start producer id=12
start producer id=13
start Consumer id=14
start Consumer id=15
start Consumer id=16
data:1 is put into queue
1*1=1
data:2 is put into queue
2*2=4
data:3 is put into queue
3*3=9
data:4 is put into queue
4*4=16
data:5 is put into queue
5*5=25
data:6 is put into queue
data:7 is put into queue
data:8 is put into queue
6*6=36
data:9 is put into queue
7*7=49
8*8=64
data:10 is put into queue
9*9=81
10*10=100
data:11 is put into queue
data:12 is put into queue
11*11=121
data:13 is put into queue
data:14 is put into queue
12*12=144
13*13=169
data:15 is put into queue
data:16 is put into queue
14*14=196
15*15=225
data:17 is put into queue
data:18 is put into queue
16*16=256
17*17=289
18*18=324
data:19 is put into queue
19*19=361
data:20 is put into queue
20*20=400
data:21 is put into queue
21*21=441
data:22 is put into queue
22*22=484
data:23 is put into queue
23*23=529
data:24 is put into queue
24*24=576
data:25 is put into queue
25*25=625
data:26 is put into queue
26*26=676
data:27 is put into queue
27*27=729
Queue方法的含义
add(E e) 如果可以立即执行此队列中的指定元素, 而不违反容量限制, 则在成功后返回 true 并在当前没有可用空间的情况下抛出 IllegalStateException。
element() 查看队列头部元素,而不移除元素
offer(E e) 在不违反容量限制的情况下,如果立即可以插入元素,则将此元素插入队列中
peek() 检索但不移除此队列的头, 如果此队列为空, 则返回 null
poll() 检索并移除此队列的头, 如果此队列为空, 则返回 null。
remove() 检索并移除此队列的头。