1、需要自定义线程的优先级,线程池中线程总是Normal
2、需要一个前台线程,线程池中线程是后台线程
非UI线程最好使用线程池创建为后台线程,常常关闭一个软件之后,仍然占有内存,就是由于创建了多个前台线程,程序关闭的时候,还有其他前台线程没有关闭。
3、需要手动终止线程,线程池不具有这种功能。
4、线程执行时间长,线程池目的是为了线程重用,省去创建新线程的额外开销,多适用于多而执行时间短的线程。线程池创建线程是滞后的,不会发现线程不够立即去创建新线程,会有个延时,以确保真正的需要创建新线程。
Executors创建线程池的弊端
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险.说明:Executors的各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM.
2)newCachedThreadPool和newScheduledThreadPool:
主要问题是线程数最多数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM.
Positive example 1:
- //org.apache.commons.lang3.concurrent.BasicThreadFactory;
- ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(
- 1,
- new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build()
- );
- ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
- //Common Thread Pool
- ExecutorService pool = new ThreadPoolExecutor(5,200,0L,TimeUnit.MILLISECONDS,
- new LinkedBlockingDeque<Runnable>(1024),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
- pool.execute(()-> System.out.println(Thread.currentThread().getName()));
- pool.shutdown();//gracefully shutdown
- <bean id="userThreadPool" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
- <property name="corePoolSize" value="10"/>
- <property name="maxPoolSize" value="100"/>
- <property name="queueCapacity" value="2000"/>
- <property name="threadFactory" value="threadFactory"/>
- <property name="rejectedExecutionHandler">
- <ref local="rejectedExecutionHandler"/>
- </property>
- </bean>
- // in code
- userThreadPool.execute(thread);