线程池基础可以参考 https://www.cnblogs.com/enhance/p/11009997.html

 

线程池创建方式:

newFixedThreadPool:

使用的构造方式为new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()),设置了corePoolSize=maxPoolSize,keepAliveTime=0(此时该参数没作用),无界队列,任务可以无限放入,当请求过多时(任务处理速度跟不上任务提交速度造成请求堆积)可能导致占用过多内存或直接导致OOM异常


newSingleThreadExector:

使用的构造方式为new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var0),基本同newFixedThreadPool,但是将线程数设置为了1,单线程,弊端和newFixedThreadPool一致


newCachedThreadPool:

使用的构造方式为new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue()),corePoolSize=0,maxPoolSize为很大的数,同步移交队列,也就是说不维护常驻线程(核心线程),每次来请求直接创建新线程来处理任务,也不使用队列缓冲,会自动回收多余线程,由于将maxPoolSize设置成Integer.MAX_VALUE,当请求很多时就可能创建过多的线程,导致资源耗尽OOM


newScheduledThreadPool:

使用的构造方式为new ThreadPoolExecutor(var1, 2147483647, 0L, TimeUnit.NANOSECONDS, new ScheduledThreadPoolExecutor.DelayedWorkQueue()),支持定时周期性执行,注意一下使用的是延迟队列,弊端同newCachedThreadPool一致

项目开发中线程池推荐创建方式

不允许使用Executors创建,而是通过ThreadPoolExecutor创建

Executors创建方式:

ExecutorService service= Executors.newFixedThreadPool(5);

public void test(){

service.execute(()->{...});

}

因为Executors创建 newFixedThreadPool & newSingleThreadExector容易造成任务无限创入LinkedBlockingQueue造成oom;对于newCachedThreadPool&newScheduledThreadPool容易造成线程无限创建造成oom

 

ThreadpoolExecutor创建方式:

@Configuration
public class ThreadConfig {
    @Bean(value="threadPoolInstance")
    public ExecutorService createThreadPoolInstance(){
    ////通过guava类库的ThreadFactoryBuilder来实现线程工厂类并设置线程名称 ThreadFactory threadFactory
=new ThreadFactoryBuilder(). setNameFormat("thread-pool-%d").build(); ExecutorService threadPool=new ThreadPoolExecutor( 5, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.AbortPolicy()); return threadPool; } }
@Service
public class BusinessThreadPoolService {
  //通过name=threadPoolInstance引用线程池实例 @Resource(name
="threadPoolInstance") private ExecutorService executorService; public void execute(){ long current=System.currentTimeMillis(); executorService.execute(new Runnable() { @Override public void run() { //business code... } } }); System.out.println(System.currentTimeMillis()-current); }
}

 

线程池任务提交方式

execute()

execute只接受runnable類型參數,不可以返回执行结果

public void execute(){
        long current=System.currentTimeMillis();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
               //business code
            }
        });
        System.out.println(System.currentTimeMillis()-current);
    }

submit()

接收runnable/callable类型参数,其中callable允许返回执行结果,允许抛出异常

通过executor.submit提交一个callable,返回一个Future,然后通过这个Future的get方法取得返回值

public void submit() throws ExecutionException, InterruptedException {
long current=System.currentTimeMillis();
Future future=executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception{
// business code
return "this is a test";
}
});
System.out.println("callable result:"+future.get());
}

 执行结果:

callable result:this is a test

 

参考文献: 

https://blog.csdn.net/qq_40428665/article/details/121651421

https://blog.csdn.net/qq_25806863/article/details/71214033

https://baijiahao.baidu.com/s?id=1701886340868428458&wfr=spider&for=pc

 

posted on 2022-07-27 18:21  colorfulworld  阅读(143)  评论(0编辑  收藏  举报