Java-多线程学习分享-4-线程池

线程池

作用:控制线程的数量,减少线程的创建和销毁

ThreadPoolExecutor

一、构造函数

public ThreadPoolExecutor(int corePoolSize, 
						  int maximumPoolSize, 
						  long keepAliveTime, 
						  TimeUnit unit, 
						  lockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
}

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;
}

前三个构造函数都是调用第四个构造函数进行初始化的。

参数:

  • corePoolSize:
    核心线程池的大小。在创建了线程池后,默认情况下,线程池中的线程数为0,当有任务来时,就会创建一个线程去执行任务。调用prestartAllCoreThreads()方法可以预设corePoolSize数量的线程,调用prestartCoreThread()方法可以预设一个线程。
  • maximumPoolSize:
    线程池最大线程数,表示在线程池中最多能创建多少个线程。
  • keepAliveTime:
    无任务执行的线程的存活时间。默认情况下,当线程数大于corePoolSize时,keepAliveTime才生效。如果调用allowCoreThreadTimeOut(boolean value)方法,当线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程数为0。
  • unit:
    keepAliveTime的时间单位:
    (1)TimeUnit.DAYS:天
    (2)TimeUnit.HOURS:小时
    (3)TimeUnit.MINUTES:分钟
    (4)TimeUnit.SECONDS:秒
    (5)TimeUnit.MILLISECONDS:毫秒
    (6)TimeUnit.MICROSECONDS:微妙
    (7)TimeUnit.NANOSECONDS:纳秒
  1. workQueue:
    阻塞队列,用来存储等待执行的任务。workQueue的类型为BlockingQueue,通常可以取下面三种类型:
    (1)ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;
    (2)LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE
    (3)SynchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。
  2. threadFactory:
    线程工厂,主要用来创建线程。
  3. handler:
    表示当拒绝处理任务时的策略:
    (1)ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
    (2)ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
    (3)ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    (4)ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

二、主要方法

  1. execute():
    向线程池提交一个任务,交由线程池去执行。
  2. submit():
    向线程池提交一个任务,交由线程池去执行,能够返回任务执行的结果。还是调用execute()去提交任务,利用Future来获取任务执行结果。
  3. shutdown()
    关闭线程池,此时线程池不再接受新的任务,它会等待所有任务执行完毕。
  4. shutdownNow()
    关闭线程池,此时线程池不再接受新的任务,并且会去尝试终止正在执行的任务。

三、线程池状态

// 表示当前线程池的状态,它是一个volatile变量用来保证线程之间的可见性
volatile int runState;
// 当初始化线程池后,线程池处于RUNNING状态
static final int RUNNING    = 0;
// 调用shutdown()方法时,线程池处于SHUTDOWN状态
static final int SHUTDOWN   = 1;
// 调用shutdownNow()方法时,线程池处于STOP状态
static final int STOP       = 2;
// 当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态
static final int TERMINATED = 3;

线程池对于新任务的处理策略

在这里插入图片描述

线程池的种类

  1. newCachedThreadPool
    可根据需要创建新线程的线程池。
    特征:
    (1)线程池中数量没有固定,可达到最大值(Interger. MAX_VALUE)
    (2)可重复使用:有新任务时,若线程池中有空闲线程,则使用空闲线程执行任务,若无则创建新线程
    (3)线程池中的线程会进行回收,回收默认时间为1分钟
    适用范围:
    执行大量小任务的场景
    使用方式:
Executors.newCachedThreadPool();
  1. newFixedThreadPool
    可重用固定线程数的线程池。
    特征:
    (1)线程池中数量固定
    (2)可重复使用,在显示关闭之前,都将一直存在
    (3)当线程数达到上限,新的任务需在队列中等待
    适用范围:
    执行长期的任务
    使用方式:
//nThreads为线程的数量 
Executors.newFixedThreadPool(int nThreads);
//nThreads为线程的数量,threadFactory为线程工厂
Executors.newFixedThreadPool(int nThreads,ThreadFactory threadFactory);
  1. newSingleThreadExecutor
    只使用单个线程的线程池。
    特征:
    (1)线程池中数量固定,且只为1
    (2)可重复使用,所有任务都使用这一个线程执行
    (3)当线程数达到上限,新的任务需在队列中等待
    适用范围:
    多个任务按照顺序执行
    使用方式:
Executors.newSingleThreadExecutor() ;
Executors.newSingleThreadExecutor(ThreadFactory threadFactory);
  1. newScheduleThreadPool
    创建可延迟执行或定期执行的线程的线程池。
    特征:
    (1)线程池中数量固定
    (2)可重复使用,在显示关闭之前,都将一直存在
    (3)当线程数达到上限,新的任务需在队列中等待
    (4) 线程可延迟执行或定期执行
    适用范围:
    需要延迟执行或定期执行的任务
    使用方式:
Executors.newScheduledThreadPool(int corePoolSize);
Executors.newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);
  1. newSingleThreadScheduledExecutor
    创建一个可延迟执行或定期执行的线程的线程池。
    特征:
    (1)线程池中数量固定,且只为1
    (2)可重复使用,在显示关闭之前,都将一直存在,所有任务都使用这一个线程执行
    (3)当线程数达到上限,新的任务需在队列中等待
    (4) 线程可延迟执行或定期执行
    适用范围:
    多个任务需要顺序的延迟执行或定期执行
    使用方式:
Executors.newSingleThreadScheduledExecutor();
Executors.newSingleThreadScheduledExecutor(ThreadFactory threadFactory);
参考:[Java并发编程:线程池的使用](https://www.cnblogs.com/dolphin0520/p/3932921.html)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值