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()
- );
Positive example 2:
- 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
Positive example 3:
- <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);
|