java 线程池简介

Java线程池的工厂类Executors类提供了4种类型的线程池

newFixedThreadPool(int nThreads)
初始化一个指定线程数的线程池,其中核心线程数和最大线程数都为nThreads,使用LinkedBlockingQuene作为阻塞队列。

newCachedThreadPool()
初始化一个可以缓存线程的线程池,默认缓存60s,核心线程数为0,最大线程数为Integer.MAX_VALUE,使用SynchronousQueue作为阻塞队列。在没有任务执行时,当线程的空闲时间超过keepAliveTime(60s),会自动释放线程资源;当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销,因此,使用时要注意控制并发的任务数,防止因创建大量的线程导致而降低性能。

newSingleThreadExecutor()
初始化只有一个线程的线程池,其中核心线程数等于最大线程数等于1,内部使用LinkedBlockingQueue作为阻塞队列,唯一的线程可以保证所提交任务的顺序执行(异常了会重新创建)。

newScheduledThreadPool(int corePoolSize)
初始化的线程池可以在指定的时间内周期性的执行所提交的任务,内部使用DelayedWorkQueue队列,在实际的业务场景中可以使用该线程池定期的同步数据。

阻塞队列

LinkedBlockingQuene
是无界的,是一个无界缓存的阻塞队列。基于链表的阻塞队列,内部维持着一个数据缓冲队列(该队列由链表构成)。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。
SynchronousQueue
无界的,是一种无缓冲的阻塞队列,一个线程在添加时必须等待另外一个线程取走,默认为非公平模式,也可以是公平模式。isEmpty()方法永远返回是true,remainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null。
DelayedWorkQueue
无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS)方法返回一个小于等于0的值时,将发生到期。即使无法使用take或poll移除未到期的元素,也不会将这些元素作为正常元素对待。例如,size方法同时返回到期和未到期元素的计数。此队列不允许使用null元素。
ArrayListBlockingQueue
是有界的,是一个有界缓存的等待队列。基于数组的阻塞队列,同LinkedBlockingQueue类似,内部维持着一个定长数据缓冲队列(该队列由数组构成)。ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置

线程池内部都是基于ThreadPoolExecutor类(Executor的子类)实现的

ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,timeUnit,workQueue,threadFactory,handle);
corePoolSize:核心线程数
maxPoolSize:最大线程数
keepAliveTime:线程存活时间(在corePore<当前线程数<maxPoolSize情况下有起作用)
timeUnit:存活时间的时间单位
workQueue:阻塞队列(用来保存等待被执行的任务),核心线程数满了会把新加入的任务放到阻塞队列中,阻塞队列满了会启用新的线程执行新的任务
handler:拒绝策略(当达到最大线程数,线程没有空闲,且阻塞队列满,继续提交新的任务就会启用拒绝策略)。

拒绝策略有以下四种取值

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
当然也可以根据应用场景实现RejectedExecutionHandler接口,自定义拒绝策略,如记录日志或持久化存储不能处理的任务。

向线程池提交任务有两种方式

	Executor.execute(Runnable command);没有返回值
	ExecutorService.submit(Callable<T> task);返回Future对象
	Future对象包括以下方法
		//取消任务
		boolean cancel(boolean mayInterruptIfRunning);
		//是否取消成功
		boolean isCancelled();
		//是否执行完成
		boolean isDone();
		//获取返回结果(如果任务没有结束会阻塞)
		V get();
		//超时等待返回结果
		 V get(long timeout, TimeUnit unit);

线程池的关闭

ThreadPoolExecutor提供了两个方法,用于线程池的关闭
    shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
    shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

线程状态

NEW(新建)、RUNNABLE(运行)、BLOCKED(锁池)、TIMED_WAITING(定时等待)、WAITING(等待)、TERMINATED(终止、结束)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值