Producer Consumer Model

    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() 检索并移除此队列的头。

Reference: Java program performance optimization

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325406532&siteId=291194637