线程池的学习及使用

线程池

ThreadPoolExecutor类

参考:https://www.cnblogs.com/dolphin0520/p/3932921.html

构造方法:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler)

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory)

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

方法的参数:

corePoolSize :核心池的大小

  1. 默认情况下,线程池中并没有任何线程 ,创建了线程池后,线程池中的线程数为0 。有任务到来才创建线程去执行任务 ,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法 ,
  2. 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中

maximumPoolSize:线程池最大线程数 ,表示在线程池中最多能创建多少个线程

keepAliveTime :表示线程没有任务执行时最多保持多久时间会终止

  1. 只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用
  2. 如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize
  3. 如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0

unit :参数keepAliveTime的时间单位,有7种取值

TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒

workQueue :阻塞队列,用来存储等待执行的任务

阻塞队列的选择

ArrayBlockingQueue;
LinkedBlockingQueue;
SynchronousQueue; 

线程池的排队策略与BlockingQueue有关

threadFactory:线程工厂,主要用来创建线程

handler:表示当拒绝处理任务时的策略,有以下四种取值:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 

常用方法:

execute(): 向线程池提交一个任务,交由线程池去执行

submit():向线程池提交任务 ,并返回任务执行的结果 ,底层调用execute()方法,只不过它利用了Future来获取任务执行结果

shutdown() 关闭线程池

shutdownNow()关闭线程池

成员变量:

private final BlockingQueue<Runnable> workQueue;              //任务缓存队列,用来存放等待执行的任务
private final ReentrantLock mainLock = new ReentrantLock();   //线程池的主要状态锁,对线程池状态(比如线程池大小
                                                              //、runState等)的改变都要使用这个锁
private final HashSet<Worker> workers = new HashSet<Worker>();  //用来存放工作集
 
private volatile long  keepAliveTime;    //线程存货时间   
private volatile boolean allowCoreThreadTimeOut;   //是否允许为核心线程设置存活时间
private volatile int   corePoolSize;     //核心池的大小(即线程池中的线程数目大于这个参数时,提交的任务会被放进任务缓存队列)
private volatile int   maximumPoolSize;   //线程池最大能容忍的线程数
 
private volatile int   poolSize;       //线程池中当前的线程数
 
private volatile RejectedExecutionHandler handler; //任务拒绝策略
 
private volatile ThreadFactory threadFactory;   //线程工厂,用来创建线程
 
private int largestPoolSize;   //用来记录线程池中曾经出现过的最大线程数
 
private long completedTaskCount;   //用来记录已经执行完毕的任务个数

volitile关键字

参考:https://www.cnblogs.com/zhengbin/p/5654805.html#_label0

volitile的特点:保证此变量对所有的线程的可见性

程序的可见性:确保执行读操作的线程 ,能适时地看到其他线程写入的值 ,为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。

可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的

也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性

在 Java 中 volatile、synchronized 和 final 实现可见性。

线程池的状态

volatile int runState;

static final int RUNNING = 0;

static final int SHUTDOWN = 1;

static final int STOP = 2;

static final int TERMINATED = 3;

runState:表示当前线程池的状态

volatile变量:保证线程之间的可见性

RUNNING :创建线程池后的状态

SHUTDOWN :调用了shutdown()方法 ,

                       此时线程池不能够接受新的任务,它会等待所有任务执行完毕 

STOP :调用了shutdownNow()方法

     此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务 

TERMINATED :当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束

哈哈哈

金麟岂能忍一世平凡 飞上了青天 天下还依然
原文地址:https://www.cnblogs.com/Auge/p/11609909.html