生产者线程负责提交用户请求,消费者线程负责具体处理生产者提交的任务,生产者和消费者之间通过共享内存缓冲区进行通信,生产者-消费者模式的核心组件是共享内存缓冲区,他作为生产者和消费者之间通信的桥梁,避免了生产者和消费者的直接通信,从而将生产者和消费者进行解耦,由于内存缓冲区的存储,允许生产者和消费者在执行速度上存在时间差。
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() 检索并移除此队列的头。