应用场景
比如我们需要上传一个excel 需要多线程校验,校验通过后直接插入数据库,这个时候我们就可以使用多线程校验 校验通过后多线程插入数据库场景,类似场景有非常多 文件上传 文件下载 文件生成 只要能用到多线程的地方都能适用上 要学会举一反三 不一一举例,废话不多说 直接上代码
代码模拟多线程生产任务 多线程同时消费的场景
运行结果示例
代码
package com.hyun.test.my;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 多线程生产-消费模式
* @author hyun
*
*/
public class Test {
/**
* 生产任务线程 需自定义
* @author hyun
*
*/
static class Producer implements Callable<String> {
//生产任务需要的参数
private final int paramData;
public Producer(int paramData) {
this.paramData = paramData;
}
@Override
public String call() throws Exception {
//模拟实际操作 随机睡眠10m内
Random random = new Random();
Thread.sleep(random.nextInt(10) * 1000);
System.out.println("paramData-" + paramData + " has producer");
return "paramData-" + paramData ;
}
}
/**
* 消费任务 需自定义
* @author hyun
*
*/
static class Consume implements Callable<String> {
//消费任务需要的参数
private final String consumeData;
public Consume(String consumeData) {
this.consumeData = consumeData;
}
@Override
public String call() {
//模拟实际消费任务 输出结果
System.out.println(consumeData + " has consume");
return "sucess-" + consumeData;
}
}
public static void main(String[] args) throws Exception {
//线程保持时间(超出线程核心数线程保持时间)
int keepAliveTime = 5;
//cpu核心数
int processors = Runtime.getRuntime().availableProcessors();
//队列长度 根据实际需要设置
BlockingQueue<Runnable> producterQueue = new ArrayBlockingQueue<>(5000);
//生产队列 如果是io操作 processors*2 否则processors+1
ThreadPoolExecutor producterThreadPool = new ThreadPoolExecutor(processors * 2, processors * 2, keepAliveTime, TimeUnit.SECONDS, producterQueue);
CompletionService<String> producterCompletion = new ExecutorCompletionService<>(producterThreadPool);
//任务数量
int taskSize = 4;
for(int i = 0; i < taskSize; i++) {
producterCompletion.submit(new Producer(i));
}
//队列长度 根据实际需要设置
BlockingQueue<Runnable> consumeQueue = new ArrayBlockingQueue<>(5000);
//消费队列 如果是io操作 processors*2 否则processors+1
ThreadPoolExecutor consumeThreadPool = new ThreadPoolExecutor(processors * 2, processors * 2, keepAliveTime, TimeUnit.SECONDS, consumeQueue);
CompletionService<String> consumeCompletion = new ExecutorCompletionService<>(producterThreadPool);
//从生产队列producterCompletion获取结果扔入消费队列consumeCompletion 根据先生产完成先消费原则
for(int i = 0; i < taskSize; i++) {
Future<String> future = producterCompletion.take();
String consumeData = future.get();
consumeCompletion.submit(new Consume(consumeData));
}
//如果需要取得消费者返回结果 否则不需要
for(int i = 0; i < taskSize; i++) {
Future<String> future = consumeCompletion.take();
String result = future.get();
//根据返回结果做相关操作
//System.out.println(result);
}
}
}