java线程池

文章目录

线程池介绍

池,从字面意思来说,就是将一定的数量放到一起,进行统一的管理和限制,从而达到统一使用线程的方式。

线程池的好处

降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。

提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

线程池一般用于执行多个不相关联的耗时任务,没有多线程的情况下,任务顺序执行,使用了线程池的话可让多个不相关联的任务同时执行。

线程池参数解析

java 复制代码
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

这是java源码中线程池创建需要的参数

  • corePoolSize:核心线程数量,在任务数量没有达到核心线程数量时,也会保持的线程数量
  • maximumPoolSize:任务队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
  • keepAliveTime:线程池中的线程数量大于 corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 keepAliveTime才会被回收销毁。
  • unit:keepAliveTime的单位
  • workQueue:当有新的任务出现,会先判断当前线程数是否达到核心线程数量,如果达到就将任务放入阻塞队列workQueue中
  • threadFactory:线程工厂,为线程池创造线程
  • hander:拒绝策略(重点)

ThreadPoolExcutor拒绝策略

ThreadPoolExecutor.AbortPolicy:抛出 RejectedExecutionException来拒绝新任务的处理。

ThreadPoolExecutor.CallerRunsPolicy:调用执行自己的线程运行任务,也就是直接在调用execute方法的线程中运行(run)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。

ThreadPoolExecutor.DiscardPolicy:不处理新任务,直接丢弃掉。

ThreadPoolExecutor.DiscardOldestPolicy:此策略将丢弃最早的未处理的任务请求。

简单来说,就是当你今天上班任务已经排满了,但是老板非要给你再加一项任务,此时你会作出一下操作:

  1. 直接拒绝老板
  2. 表示自己不会做,并且指出谁提出,谁负责
  3. 将自己最早的任务丢弃,来执行新任务
  4. 将老板给的任务直接丢弃

线程池使用案例

方式一:使用ThreadPoolExecutor

java 复制代码
		 public static void main(String[] args) {
		ExecutorService service1=Executors.newSingleThreadExecutor();
        ThreadFactory threadFactory=Executors.defaultThreadFactory();
        BlockingQueue<Runnable> workqueue=new ArrayBlockingQueue<>(100);
        ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(10,20,10, 					  TimeUnit.SECONDS,workqueue,threadFactory);
        for(int i=0;i<1000;i++){
            int a=i;
           poolExecutor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(a+" "+Thread.currentThread().getName());
                }
            });
        }
        poolExecutor.shutdownNow();
}

方法二:使用Executors

复制代码
 public static void main(String[] args) {
 
        ExecutorService service = Executors.newCachedThreadPool();
        ExecutorService temp=Executors.newFixedThreadPool(10);
        ExecutorService service1=Executors.newSingleThreadExecutor();
        ExecutorService service2=Executors.newScheduledThreadPool(10);
        for(int i=0;i<1000;i++){
            int a=i;
           poolExecutor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(a+" "+Thread.currentThread().getName());
                }
            });
        }
        poolExecutor.shutdownNow();
    }

FixedThreadPool:固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。

SingleThreadExecutor: 只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。

CachedThreadPool: 可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。

ScheduledThreadPool:给定的延迟后运行任务或者定期执行任务的线程池。

相关推荐
异常君1 分钟前
线程池隐患解析:为何阿里巴巴拒绝 Executors
java·后端·代码规范
Java技术小馆7 分钟前
SpringBoot中暗藏的设计模式
java·面试·架构
xiguolangzi7 分钟前
《springBoot3 中使用redis》
java
꧁坚持很酷꧂10 分钟前
配置Ubuntu18.04中的Qt Creator为中文(图文详解)
开发语言·qt·ubuntu
李菠菜14 分钟前
非SpringBoot环境下Jedis集群操作Redis实战指南
java·redis
不当菜虚困27 分钟前
JAVA设计模式——(四)门面模式
java·开发语言·设计模式
ruyingcai66666627 分钟前
用python进行OCR识别
开发语言·python·ocr
m0Java门徒35 分钟前
面向对象编程核心:封装、继承、多态与 static 关键字深度解析
java·运维·开发语言·intellij-idea·idea
liuweidong080237 分钟前
【Pandas】pandas DataFrame radd
开发语言·python·pandas
无心水1 小时前
【Java面试笔记:基础】8.对比Vector、ArrayList、LinkedList有何区别?
java·笔记·面试·vector·arraylist·linkedlist