本人并发小白,如果有可以优化的地方欢迎评论交流~
题目如下:
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());
}
}