Java线程池详解

导读:本篇文章讲解 Java线程池详解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

这篇文章和大家讲讲Java中的线程池:

常见的4中线程池:

1.Executors.newCachedThreadPool();
创建一个可缓存的线程池,如果线程长度超过处理需求,可灵活处理回收空闲线程,若无可回收线程,则新建线程;
在这里插入图片描述
2.Executors.newFixedThreadPool(5);
创建指定数量的线程池,可控制线程最大并发数,超出的线程会在队列中等待;
在这里插入图片描述
3.Executors.newScheduledThreadPool(10);
创建一个定长线程池,支持定时及周期性任务回收;
在这里插入图片描述
可知道多长时间后执行,专门做定时任务的线程池;
4.Executors.newSingleThreadExecutor();
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务
在这里插入图片描述
5.**Executors.defaultThreadFactory();**默认线程池
在这里插入图片描述

创建线程池的2钟方法:

  1. 第一种:
public static ExecutorService service = Executors.newFixedThreadPool(10);
public static class Thread01 extends Thread{
    @Override
    public void run() {
        System.out.println("当前线程"+Thread.currentThread().getId());
        int i = 10/2;
        System.out.println("运行线程"+i);
    }
}
public static class Runnable01 implements Runnable{
    @Override
    public void run() {
        System.out.println("当前线程"+Thread.currentThread().getId());
        int i = 10/2;
        System.out.println("运行线程"+i);
    }
}

启动:

service.execute(new Thread01());
service.execute(new Runnable01());
  1. 第二种
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
        200,
        10,
        TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(10000),
        Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.AbortPolicy());

此种方法创建的线程池有7大参数,我们知道了其意义,才可合理的运用他,我们进入其底层实现,如图 :
在这里插入图片描述

  • int corePoolSize:核心线程数,其一直会在线程池保存(即时系统空闲,除非设置了allowCoreThreadTimeOut),即线程池创建以后就准备就绪的线程数量,就等待来接收异步任务.
  • int maximumPoolSize:最大线程数量,控制资源.
  • Long keepAliveTime:存活时间,如果当前的线程数量>核心数量,释放空闲线程(maximumPoolSize-corePoolSize)(只要线程空闲>存活时间).
  • TimeUnit unit:存活时间单位. BlockingQueue
  • workQueue:阻塞队列,如果任务有很多,多余的任务会先放在队列中,有线程空闲后,便会从队列中取新的线程继续执行.
  • ThreadFactory threadFactory:线程创建工厂. RejectedExecutionHandler
  • handler(拒绝策略):如果队列满了,存不了更多的任务,按照我们指定的拒绝策略拒绝执行我们的任务.

拒绝策略:

在这里插入图片描述
默认util包下有4种拒绝策略:
1.丢弃最老的任务
2.直接丢弃新来的任务,并且抛出异常
3.直接调用run方法的策略,相当于做了同步调用
4.直接丢弃新来的任务,但不 抛出异常

线程池工作顺序/流程:

1.线程池首先创建,准备好corePoolSize数量的核心线程,准备接收任务;
2.新来的任务,用corePoolSize准备好的空闲线程执行.
2.1 如果corePoolSize被任务占满,就将任务放在阻塞队列中,一旦有空闲的corePoolSize线程,便自己去任务对列中获取任务执行
2.2如果阻塞队列也满了,就直接开新线程执行,最大只能开到maximumPoolSize;
2.3如果maximumPoolSize也满了,maximumPoolSize-corePoolSize数量的空闲线程会在keepAliveTime指定的时间后自动销毁,最终保持到corePoolSize数量的线程.
2.4 如果线程开到了maximumPoolSize数量,还有新的任务进来,就会使用reject指定的拒绝策略来进行处理;
3所以线程的创建都是由threadFactory创建.

注意:new LinkedBlockingQueue<>();默认是Integer的最大值;(可能导致内存不够,故一定要存为定值数量)

使用线程池的好处:

  1. 降低资源消耗
    通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗
  2. 提高响应速度
    因为线程池中的线程没有没有超过线程池的最大上限时,有的线程处于等待分配任务状态,当任务来临时无需创建新的线程就能执行;
  3. 提高线程的可管理性
    线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销;无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,

笔者刚开始运营公众号啦,感兴趣的可关注我的公众号,欢迎交流!

image.png

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96841.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!