java 线程池的核心组成部分及其运行机制

本文详解 ThreadPoolExecutor 类

构造方法:

// 1.8 源码 JDK 注释
public ThreadPoolExecutor(
        int corePoolSize,			
	//  the number of threads to keep in the pool, even if they are idle, unless is set   
	//  保持在池中的线程数量,即是他们空闲也在池中,除非设置他们.  ----核心线程数量.
	int maximumPoolSize,
	//  the maximum number of threads to allow in the pool
        //  池中允许的最大线程数
	long keepAliveTime,
        // when the number of threads is greater than the core, this is the maximum time that         
        // excess idle threads will wait for new tasks before terminating.
	//  当线程数大于核心时,多余空闲线程在终止之前等待新任务的最长时间.
	TimeUnit unit,				
	// the time unit for the argument
	//  等待的时间单位
	BlockingQueue<Runnable> workQueue,	
	// the queue to use for holding tasks before they are executed.  This queue will hold 
        // only the tasks submitted by the method.
	// 在执行任务之前用于保存任务的队列。 此队列仅包含该方法提交的任务。
	ThreadFactory threadFactory,	
	// 线程工厂
	RejectedExecutionHandler handler) {}	// 拒绝策略

运行机制:
        通过 new 创建线程池时, 除非调用 prestartAllCoreThreads / prestartCoreThread 方法启动核心线程,
        否则即使工作队列中存在任务,同样也不会执行.

/**
*  -通过 new 创建线程池时, 除非调用 prestartAllCoreThreads / prestartCoreThread 方法启动核心线程,
*  -否则即使工作队列中存在任务,同样也不会执行.
*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(8, 20, 3L, TimeUnit.SECONDS, linkedBlockingDeque);
		
/**
 * Starts all core threads, causing them to idly wait for work. This
* overrides the default policy of starting core threads only when
* new tasks are executed.
*	-启动所有核心线程,让它们无空闲的等待工作。 这将覆盖仅在执行新任务时启动核心线程的默认策略。
* -手动启动线程池.
* @return the number of threads started
*/
threadPoolExecutor.prestartAllCoreThreads();

    RejectedExecutionHandler:(详见JDK源码)
        实现类:
            AbortPolicy : 默认, 中止策略,直接抛 RejectedExecutionException(拒绝执行异常.)
                AbortPolicyWithReport: 中止时记录警告信息. 它是上面策略的子类.
            CallerRunsPolicy : 只要线程池没有关闭. 让当前线程直接执行被丢弃的任务.
            DiscardPolicy : 什么都不干, 直接丢弃任务.
            DiscardOldestPolicy : 丢弃最老的一个请求(任务队列里第一个),再尝试提交任务.

线程池的使用建议:
    避免使用 Executor 框架去创建线程池.
        newFixedThreadPool  newSingleThreadExecutor
        允许的请求队列长度为 Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致OOM.
        这个会撑爆你设置的项目内存.
        newCachedThreadPool newScheduledThreadPool
        允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
        这个会撑爆你整台服务器还剩的可用内存.不依赖你设置的项目内存.
    
    核心线程数量不要太大.
    
    要处理异常.
    /*    1. execute 没有返回值.
     *     submit  有返回值
     *  2. execute 直接抛出异常
     *     submit 如果发生异常,不会直接抛出,而是在返回值里get才会抛出.
     */

/**
 * - 测试 submit 和 execute 的区别
 * @author 
 * @date 
 */
public class Submit_Execute {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		BlockingQueue<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<>(64);
		
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 8, 3L, TimeUnit.SECONDS, linkedBlockingDeque);
		try {
			for (int i = 0; i < 32; i++) {
				Future<?> submit = threadPoolExecutor.submit(() -> {
					System.out.println(Thread.currentThread().getName());
					return Integer.parseInt("abc");
				});
				submit.get();
			}
		} finally {
			threadPoolExecutor.shutdown();
		}
		
		/*	1. execute 没有返回值.
		 *     submit  有返回值
		 *  2. execute 直接抛出异常
		 *     submit 如果发生异常,不会直接抛出,而是在返回值里get才会抛出.
		 */
	}
}

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值