【经典】JAVA线程池

JAVA多线程的五个状态:

Running:运行态,该状态下线程池能够接受新的任务

Shutdown:该状态下不接受新的任务,但会继续处理已经添加的任务。

Stop:该状态下不接受新的任务,并且会中断正在执行的任务,同时删除未处理的任务;

Tidying:指当前所有的任务已经停止;

Terminated:该状态表示线程池彻底停止。

 

多线程创建方法一

JAVA中我们用JUC包下的ThreadPoolExecutor来创建线程池,ThreadPoolExecutor提供了四个构造方法:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)


public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)


public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)


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

其中:

corePoolSize:指线程池的容量大小;如果调用prestartAllCoreThreads(),则会提前初始化所以线程。

maximumPoolSize:指线程最大数;如果corePoolSize满时会创建线程直到线程数等于maximumPoolSize;如果线程数等于maximumPoolSize后,下一个任务将被添加到线程等待队列(第五个参数);

keepAliveTime:指线程存活时间

timeUnit:存活时间的单位

BlockingQueue<Runnable> workQueue:线程等待队列类型;

BlockingQueue,有以下几种

ArrayBlockingQueue,必须制定长度,其底层只用一个锁,同一时间点上,只能有一个入队或出队的操作;

LinkedBlockingQueue,默认长度的Integer的最大值,底层维护着两把锁,一个用于入队,一个用于出队;

SynchronousQueue, 没有容量的无缓冲等待队列,当有任务时它直接将任务交给消费者。

DelayedWordQueue, 无界的延时队列,即可以指定队列里的任务被延时消费。

依据数组和链接的特点,可以适当选择;

因为很多业务都是出入队列高并发,所以大多数情况下,LinkedBlockingQueue一般情况下效率比ArrayBlockingQueue效率高;

ThreadFactory:线程工程,在创建线程时候用到;可以通过Executors.defaulThreadFactory()获取;

RejectedExecutionHandler:拒绝策略;当线程队列满时(线程大于maximunPoolSize,且workQueue满时),新进来的任务要这么处理;默认是AbortPolicy,即直接抛异常;

RejectedExecutionHandler包含:

       1、AbortPolicy,默认的拒绝策略,即抛异常;

       2、CallerRunsPolicy,调用者所在的线程来执行,不一定是主线程,有可能是线程掉线程;

       3、DiscardOldestPolicy,丢弃队列中最老的任务,并执行当前任务;

       4、DiscardPolicy,直接丢弃新任务;

拒绝策略是ThreadPoolExecutor的内部类,需要时使用,new ThreadPoolExecutor.AbortPolicy();

也可以自定义拒绝策略:实现RejectedExecutionHandler;

 

 多线程的创建方法二

  该方式也是官方推荐的:

 FixedThreadPool:必须指定线程数CoreSize,coreSize==maximumPoolSize ,底层用的是基于链表的队列;

  Executors.newFixedThreadPool(int coreSize) : 

  Executors.newFixedThreadPool(int coreSize, ThreadFactory threadFacotry)

 

  CachedThreadPool: 默认coreSize=0;maximumPoolSize=Integer.MAX_VALUE; 底层是SychronousQueue无缓冲队列

  Executors.newCachedThreadPool(); 

  Executors.newCachedThreadPool(ThreadFactory threadFacory);

 

 ScheduledThreadPool:必须指定coreSize;  maximumPoolSize=Integer.MAX_VALUE;底层使用的是DelayedWorkQueue延迟队列。

 Executors.newScheduledThreadPool(int coreSize);

 Executors.newScheduledThreadPool(int coreSize, ThreadFactory threadFactory);

 

SingleThreadExecutor:和FixedThreadPool一样,只是coreSize=1;(不常用)

SingleThreadScheduledExecutor:即是延时单例的;(不常用)

 

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章