The producer thread is responsible for submitting user requests, and the consumer thread is responsible for processing the tasks submitted by the producer. The producer and the consumer communicate through the shared memory buffer. The core component of the producer-consumer model is the shared memory buffer. As a bridge of communication between producers and consumers, it avoids direct communication between producers and consumers, thereby decoupling producers and consumers. Due to the storage of memory buffers, it allows producers and consumers to execute There is a time difference in speed.
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();//Get the head element 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(); } }
output result
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
Meaning of Queue method
add(E e) 如果可以立即执行此队列中的指定元素, 而不违反容量限制, 则在成功后返回 true 并在当前没有可用空间的情况下抛出 IllegalStateException。
element() 查看队列头部元素,而不移除元素
offer(E e) 在不违反容量限制的情况下,如果立即可以插入元素,则将此元素插入队列中
peek() 检索但不移除此队列的头, 如果此队列为空, 则返回 null
poll() 检索并移除此队列的头, 如果此队列为空, 则返回 null。
remove() 检索并移除此队列的头。