线程池在execute添加线程的策略

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread.  If it fails, we know we are shut down or saturated
     * and so reject the task.
     */
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) { // 1.
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) { // 2.
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    else if (!addWorker(command, false)) // 3.
        reject(command);
}

1.如果运行的线程少于corePoolSize的线程,那么尝试使用addWorker()方法,加入新的线程,在addWorker里添加失败会返回false,会自动检查线程运行状态runState和 工作线程数量workerCount,通过返回false来防止错误警报,从而在不应该添加 线程的时候添加线程。

2.否则添加这个任务到等待队列workQueue,如果一个任务可以成功地进入等待队列,仍然需要 检查是否应该添加一个线程 (因为自上次检查以来已有的线程已经死亡)或者自进入该方法后池关闭。重新检查状态,如果停止,则回滚队列,如果没有,则启动一个新的线程。

3.如果不能对任务进行排队(即等待队列workQueue塞满),则尝试添加一个新的线程。如果失败了(已经运行中的线程数量大于在实例化时指定的 maximumPoolSize 会返回false,线程池被关闭或者符合停止的条件也会返回false),我们就知道线程池被关闭或饱和了,所以拒绝这个任务执行reject()方法,reject方法会执行在初始化线程池 传入的处理策略,默认采用AbortPolicy,抛出RejectedExecutionException策略拒绝执行。


阿里java规范手册里规定,线程资源必须通过线程池提供。不允许在应用中自行显式创建线程不允许直接使用线程池内置的new方法来创建线程池。


Executors提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService 接口

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
 
public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);//请求队列长度为 Integer.MAX_VALUE
}

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,    //允许的创建线程数量为 Integer.MAX_VALUE 
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>()); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值