package com.shuige.business.train.util;
import org.apache.poi.ss.formula.functions.T;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Description:符合阿里巴巴规范的线程池
* User: zhouzhou
* Date: 2019-01-15
* Time: 14:19
*/
public class ThreadPoolUtil {
public static ThreadPoolExecutor threadPool;
/**
* 无返回值直接执行, 管他娘的
* @param runnable
*/
public static void execute(Runnable runnable){
getThreadPool().execute(runnable);
}
/**
* 返回值直接执行, 管他娘的
* @param callable
*/
public static <T> Future<T> submit(Callable<T> callable){
return getThreadPool().submit(callable);
}
/**
* dcs获取线程池
* @return 线程池对象
*/
public static ThreadPoolExecutor getThreadPool() {
if (threadPool != null) {
return threadPool;
} else {
synchronized (ThreadPoolUtil.class) {
if (threadPool == null) {
threadPool = new ThreadPoolExecutor(8, 16, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(200000), new ThreadPoolExecutor.CallerRunsPolicy());
}
return threadPool;
}
}
}
}
实际中如何实用呢?
编写Callable类
class TestCallable implements Callable<String> {
private String message;
public TestCallable(String message) {
this.message = message;
}
@Override
public String call() throws Exception {
Thread.sleep(300);
System.out.println(String.format("打印消息%s", message));
return "OK";
}
}
编写测试方法
@Test
public void test() throws Exception{
long start = System.currentTimeMillis();
List<Future> futureList = new ArrayList();
// 发送10次消息
for (int i = 0; i < 10; i++) {
try {
Future<String> messageFuture = ThreadPoolUtils.submit(new TestCallable(String.format("这是第{%s}条消息", i)));
futureList.add(messageFuture);
} catch (Exception e) {
e.printStackTrace();
}
}
for (Future<String> message : futureList) {
String messageData = message.get();
}
System.out.println(String.format("共计耗时{%s}毫秒", System.currentTimeMillis() - start));
}
结果打印: 10条消息耗时原来需要3000毫秒, 现在只需要600+毫秒,因为线程大小是5,所以阻塞时间有300ms的偏差,实际运用中,多线程的线程数,也要管理起来, 具体可以参考我的其他文档.
打印消息这是第{2}条消息
打印消息这是第{0}条消息
打印消息这是第{4}条消息
打印消息这是第{1}条消息
打印消息这是第{3}条消息
打印消息这是第{8}条消息
打印消息这是第{5}条消息
打印消息这是第{9}条消息
打印消息这是第{6}条消息
打印消息这是第{7}条消息
共计耗时{661}毫秒
当然如果你不想编写Callable类,直接使用匿名内部类(建议)
/**
* Description:
* User: zhouzhou
* Date: 2018-08-23
* Time: 13:28
*/
public class ThreadDemoTest {
@Test
public void test() throws Exception{
long start = System.currentTimeMillis();
List<Future> futureList = new ArrayList();
// 发送10次消息
for (int i = 0; i < 10; i++) {
try {
String msg = String.format("这是第{%s}条消息", i);
Future<String> messageFuture = ThreadPoolUtils.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(300);
System.out.println(String.format("打印消息%s", msg));
return "OK";
}
});
futureList.add(messageFuture);
} catch (Exception e) {
e.printStackTrace();
}
}
for (Future<String> message : futureList) {
String messageData = message.get();
}
System.out.println(String.format("共计耗时{%s}毫秒", System.currentTimeMillis() - start));
}
}
结果示意:
打印消息这是第{1}条消息
打印消息这是第{2}条消息
打印消息这是第{0}条消息
打印消息这是第{4}条消息
打印消息这是第{3}条消息
打印消息这是第{9}条消息
打印消息这是第{6}条消息
打印消息这是第{8}条消息
打印消息这是第{7}条消息
打印消息这是第{5}条消息
共计耗时{702}毫秒