本人併發小白,如果有可以優化的地方歡迎評論交流~
題目如下:
15個生產者生產1000條數據(從1開始,每生產一條加1),並向消息隊列中存放字符串(“第m個生產者生產數據n”),同時3個消費者消費數據,並將數據n累加最後輸出
代碼如下:
生產者:
package com.lcy.thread.parta;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 功能描述:生產者
*
* @author liuchaoyong
* @version 1.0
* @date 2020/1/7 19:49
*/
public class Producer implements Runnable{
LinkedBlockingQueue<String> queue;
private AtomicInteger data;
Producer(LinkedBlockingQueue<String> queue,AtomicInteger data){
this.queue=queue;
this.data=data;
}
@Override
public void run() {
//小於1000就一直生產
while (data.get() <= Test.MAX) {
String s = "第" + Thread.currentThread().getName() + "個生產者生產" + data.getAndIncrement();
System.out.println(s);
queue.offer(s);
}
}
}
消費者:
package com.lcy.thread.parta;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 功能描述:消費者
*
* @author liuchaoyong
* @version 1.0
* @date 2020/1/7 20:00
*/
public class Consumer implements Runnable{
private LinkedBlockingQueue<String> queue;
private AtomicInteger sum;
private AtomicInteger time;
Consumer(LinkedBlockingQueue<String> queue,AtomicInteger time,AtomicInteger sum){
this.queue=queue;
this.time=time;
this.sum=sum;
}
@Override
public void run() {
while (time.get() != Test.MAX) {
String poll = queue.poll();
if (poll != null) {
sum.getAndAdd(Integer.parseInt(poll.substring(poll.lastIndexOf("產") + 1)));
time.getAndIncrement();
}
}
}
}
測試類:
package com.lcy.thread.parta;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 功能描述:
*
* @author liuchaoyong
* @version 1.0
* @date 2020/1/7 20:07
*/
public class Test {
public static final int MAX = 1000;
/**
*消息隊列
*/
private static LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
/**
* 生產者當前生產的數據
*/
private static AtomicInteger data = new AtomicInteger(1);
/**
* 累加器
*/
private static AtomicInteger sum = new AtomicInteger(0);
/**
* 消費者當前消費次數
*/
private static AtomicInteger time = new AtomicInteger(0);
/**
* 生產者線程池
*/
private static ThreadPoolExecutor producerExecutor;
/**
* 消費者線程池
*/
private static ThreadPoolExecutor consumerExecutor;
static {
producerExecutor = new ThreadPoolExecutor(15, 15, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadFactory() {
private AtomicInteger num = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, num.incrementAndGet() + "");
}
});
consumerExecutor = new ThreadPoolExecutor(3, 3, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), (ThreadFactory) Thread::new);
}
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
producerExecutor.execute(new Producer(queue, data));
}
for (int i = 0; i < 3; i++) {
consumerExecutor.execute(new Consumer(queue,time, sum));
}
//加到1000了就關閉生產者,並等待剩餘生產者任務結束
do {
if (data.get() == MAX && !producerExecutor.isShutdown()) {
producerExecutor.shutdown();
}
} while (!producerExecutor.isTerminated());
//取了1000次數據就關閉消費者,並等待消費者任務結束
while (true) {
if (time.get() == MAX && !consumerExecutor.isShutdown()) {
consumerExecutor.shutdown();
break;
}
}
System.out.println(sum.get());
}
}