线程池总结

问题

项目中我用线程池实现的一个数据提取功能,在生产环境报OOM,当时也是一头包,在网上乱找原因,现在做一下总结。

分析

核心参数

ThreadPoolExecutor构造器
通过execute()方法源码可看到:

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
		int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
}

提交优先级:核心线程->BlockingQueue队列->非核心线程
执行优先级:核心线程->非核心线程->BlockingQueue

阿里巴巴规约

阿里巴巴规约
Executors的静态方法:

	//**newFixedThreadPool**
	public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    
    //**newSingleThreadExecutor**
	public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
    
    public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
        //由于BlockingQueue的长度是Integer.MAX_VALUE,相当于可以无限制的添加任务,到一定程度会引起永久代空间不足,OOM
    }
	
	//**newCachedThreadPool**由于最大线程数是Integer.MAX_VALUE,可能会引起CPU创建很多线程,导致程序卡死
	public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

	//**ScheduledThreadPoolExecutor**跟newCachedThreadPooll一样可能会导致程序卡死
	public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

队列参考文章:
BlockingQueue及其实现参考

拒绝策略

  1. AbortPolicy: A handler for rejected tasks that throws a RejectedExecutionException.(默认为这个拒绝策略
  2. DiscardPolicy: A handler for rejected tasks that silently discards the rejected task.
  3. DiscardOldestPolicy: A handler for rejected tasks that discards the oldest unhandled request and then retries execute, unless the executor is shut down, in which case the task is discarded.
  4. CallerRunsPolicy: A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method, unless the executor has been shut down, in which case the task is discarded.

多线程下的异常捕获问题参考文章:
JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止

线程池之坑都被你踩完了我踩啥:
没想到,这么简单的线程池用法,深藏这么多坑

踏破铁鞋,学无止境,还有很长路要走。
今天一朋友生日,祝他生日快乐,写这文章顺便也希望他能好好理解线程池原理@_+ !

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值