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 小时前
【Java后端】Spring Boot 集成 MyBatis-Plus 全攻略
java·spring boot·mybatis
阿珊和她的猫4 小时前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
fouryears_234176 小时前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~7 小时前
C#---StopWatch类
开发语言·c#
桦说编程8 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen8 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研8 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
没有bug.的程序员9 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋9 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
cui__OaO10 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习