Java线程池

使用Executors创建

import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(
//要运行的线程
);
不足

容易资源耗尽

  1. newFixedThreadPool和newSingleThreadExecutor:

主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。

  1. newCachedThreadPool和newScheduledThreadPool:

主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

推荐方案1:手动创建,指定线程池大小

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;

ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
                new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
        executorService.execute(()->{
            System.out.println("testScheduledExecutorService:"+System.currentTimeMillis());
        });

其中

ScheduledExecutorService extends ExecutorService
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)

推荐方案2:使用spring创建

//配置
<bean id="cmqExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 线程池维护线程的最少数量 -->
        <property name="corePoolSize" value="5" />
        <!-- 允许的空闲时间 -->
        <property name="keepAliveSeconds" value="200" />
        <!-- 线程池维护线程的最大数量 -->
        <property name="maxPoolSize" value="200" />
        <!-- 缓存队列 -->
        <property name="queueCapacity" value="1000" />
        <!-- 对拒绝task的处理策略 -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
        </property>
</bean>


//调用
@Autowired
private ThreadPoolTaskExecutor cmqExecutor;

cmqExecutor.execute(
  ()->{
     //TODO
  }
);

线程执行优先级

核心线程corePoolSize>任务队列workQueue>最大线程 maximumPoolSize>如果三者都满则使用handler处理被拒绝的任务。

  • 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

  • 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

  • 如果此时线程池中的数量大于等于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maxPoolSize,建新的线程来处理被添加的任务。

  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maxPoolSize,那么通过handler所指定的策略来处理此任务。

  • 当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 序言 近日后台需要一些数据,需要从网上爬取,但是爬取的过程中,由于访问速度太频繁,造成IP被封,最终通过线程池解决...
    HusterYP阅读 853评论 0 3
  • 本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...
    Android进阶与总结阅读 837评论 0 5
  • 本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...
    Ruheng阅读 7,183评论 1 64
  • 更多 Java 并发编程方面的文章,请参见文集《Java 并发编程》 线程组 Thread Group 线程的集合...
    专职跑龙套阅读 1,366评论 0 3
  • 瞎忙活,生活已不规律。 忙起来少了思考的时间,少了烦忧。 闲时却是无聊,徒增烦恼。
    下温水阅读 202评论 0 0