一、背景說明
隨着Jdk 升級到1.8後,項目中使用parallelStream 等並行流調用方式逐漸增多,在進行jstack 查看線程時,發現大量的ForkJoinPool.commonPool-worker-xx線程,但是無法具體定位到是哪個業務線在使用,考慮使用自定義線程池使用parallelStream,詳細代碼如下所示
二、自定義線程池
具體實現代碼如下所示:
package com.timer.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.atomic.AtomicLong;
public class ForkJoinPoolFactory {
//自定義線程池
private static class DefaultForkJoinPoolThread extends ForkJoinWorkerThread {
protected DefaultForkJoinPoolThread(ForkJoinPool pool) {
super(pool);
}
}
/**
* 獲取線程創建工廠
* @param trheadName 線程名稱
* @return
*/
private ForkJoinPool.ForkJoinWorkerThreadFactory getForkJoinFactory(String trheadName){
ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
final AtomicLong count = new AtomicLong(0);
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
DefaultForkJoinPoolThread thread = new DefaultForkJoinPoolThread(pool);
thread.setName(trheadName+"-"+count.getAndIncrement());
return thread;
}
};
return factory;
}
/**
* 獲取並行線程池
* @param trheadName 線程名稱
* @return
*/
public ForkJoinPool get(String trheadName){
ForkJoinPool.ForkJoinWorkerThreadFactory factory = getForkJoinFactory(trheadName);
ForkJoinPool customThreadPool = new ForkJoinPool(4,
factory,
null,
false);
return customThreadPool;
}
/**
* 獲取並行線程池
* @param parallelism 線程數量
* @param trheadName 線程名稱
* @return
*/
public ForkJoinPool get(int parallelism,String trheadName){
ForkJoinPool.ForkJoinWorkerThreadFactory factory = getForkJoinFactory(trheadName);
ForkJoinPool customThreadPool = new ForkJoinPool(parallelism,
factory,
null,
false);
return customThreadPool;
}
public static void main(String[] args) {
try{
/***指定線程名稱調用**/
ForkJoinPool customThreadPool = new ForkJoinPoolFactory().get(4,"測試線程");
List<Long> names = new ArrayList<>();
for(int i = 1;i<50;i++){
names.add(new Long(i));
}
/***調用方式一 存在返回值 支持返回值 子線程全部走完後,纔會繼續向下走**/
Object obj = customThreadPool.submit(
new Callable<Object>() {
@Override
public Object call() {
names.parallelStream().forEach(o->{
System.out.println("方式一===="+Thread.currentThread().getName()+"===="+o);
});
return null;
}
}
).get();
/***與上面代碼效果一致**/
Object obj2 = customThreadPool.submit(()->{names.parallelStream().forEach(o->
{
System.out.println("方式一===="+Thread.currentThread().getName()+"===="+o);
});
}).get();
System.out.println("=======================1");
/***調用方式二 不需要返回值 完全並行,不等待子線程是否執行完成 **/
customThreadPool.submit(()->{
names.parallelStream().forEach(o->{
System.out.println("方式二===="+Thread.currentThread().getName()+"===="+o);
});
});
System.out.println("=======================2");
}catch (Throwable e){}
}
}