线程(Thread)和线程池(ThreadPoolExecutor)

1、什么是线程(Thread)和线程池(ThreadPool) 线程

线程:进程中负责程序执行的执行单元。一个进程至少有一个线程。

线程池:基本思想是对象池的思想,开辟一块内存空间,里面存放一个重操作的对象,里面存放众多的线程,池中的线程执行调度由池管理器来处理,当需要线程执行任务时,从线程池中获取一个,执行完该任务后,将线程重新放入线程池中

2、为什么需要线程池

java的线程是重量级的,如果频繁的创建和销毁会严重影响程序的性能

3、ThreadPoolExecutor

       3.1 ThreadPoolExecutor参数


  • corePoolSize    核心线程数
  • maximumPoolSize   最大线程数
  • keepAliveTime         线程空闲存活时间
  • workQueue              任务队列
    • 无界阻塞队列    比如LinkedBlockingQueue,来多少任务,就放多少任务
    • 有界阻塞队列    比如ArrayBlockingQueue,只能存放指定大小的任务
    • 同步移交           比如SynchronousQueue不存储任务任务,接收到任务后直接转移                            给其他线程
  • threadFactory           线程工厂
  • handler                     拒绝策略
    • AbortPolicy:使用这种策略的线程池,将在无法继续接受新任务时,给任务提交方抛出RejectedExecutionException,让他们决定要如何处理;
    • CallerRunsPolicy:这个策略,顾名思义,将把任务交给调用方所在的线程去执行;
    • DiscardPolicy:直接丢弃掉新来的任务;
    • DiscardOldestPolicy:丢弃最旧的一条任务,其实就是丢失blockingQueue.poll()返回的那条任务,要注意,如果你使用的是PriorityBlockingQueue优先级队列作为你的任务队列,那么这个策略将会丢弃优先级最高的任务,所以一般情况下,PriorityBlockingQueue和DiscardOldestPolicy不会同时使用

    3.2 Executors的不同类型的线程池

           

Executors类提供了创建5种经典常用的线程池的静态方法,下面,让我们来分析一下

  • newCachedThreadPool
//无参创建cacheThreadPool的方法
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}//传入ThreadFactory作为参数
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}复制代码

根据cacheThreadPool的创建参数,我们可以得出它的一些特性,corePoolSize(核心线程数)为0,但是maxmumPoolSize为Integer.MAX_VALUE,这样我们可以认为最大创建的线程数为无穷大。线程空闲销毁时间为60s。任务队列是synchronousQueue,这是一个没有存储空间的队列,一直有一个消费者在等待任务写入,当任务写入后会被立即取出消费,因此,这个线程池的特点是当有任务写入后,会检查当前是否有可用线程,如果有可用线程,则使用该可用线程去执行该任务,如果没有可用线程,则会创建一条线程来执行该任务。任务执行完毕后,该线程在设定的时间内未被再次使用,则会被销毁。

使用场景:实时性要求高,任务多且每个任务耗时少。

  • newFixedThreadPool
//参数nThreads  设置当前线程数
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(),
                                  threadFactory);
}复制代码

corePoolSize(核心线程数)和maxmumPoolSize(最大线程数)为参数nThread,线程空闲时间为0L,则意味着该线程不会被回收销毁,知道该线程池被shutDown()。workQueue为LinkedBlockingQueue,该队列为无边界队列,最大的存储空间为Integer.MAX_VALUE,可以认为能无限存放任务,因此该线程池的特点是当线程池中的线程数小于核心线程数且当前不存在可用线程,则会优先创建线程,直到线程数等于最大线程数,如果继续添加任务,则会放入队列,直到有可用线程才会处理任务队列中的任务。

使用场景:对实时性要求不高的任务。



转载于:https://juejin.im/post/5c617f6251882562ee643e3b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值