线程池执行原理

前言

在刚接触多线程编程时,曾写过类似于如下代码:

public static void main(String[] args) throws InterruptedException {
   
    ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10, 20, 1, TimeUnit.HOURS, new LinkedBlockingDeque<>());
    Thread thread = new Thread(() -> System.out.println("子线程运行"));
    poolExecutor.submit(thread);
    thread.join();
}

既想要使用线程池来管理线程,又想要阻塞当前线程。结果运行时发现thread.join()方法并没有起作用,究其原因,thread线程并没有启动,然而确实有子线程运行并打印了数据,因此有必要了解一下submit()方法的执行原理。

ThreadPoolExecutor

ThreadPoolExecutor类图

从上图可以发现 ThreadPoolExecutor类相关的继承关系,而submit(Runnable)方法在其父类AbstractExecutorService中有具体实现:

public Future<?> submit(Runnable task) {
   
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
   
    return new FutureTask<T>(runnable, value);
}

从这里就能发现原有线程不启动的原因了,submit()方法接收一个Runnable参数对象,封装成FutureTask,并执行该任务,而不是启动原来的线程。

线程池处理任务的流程

ctl

线程池内部维护一个AtomicInteger类型的变量ctl,通过位运算的方式以该数字表示线程池的两个状态,原理为:二进制高 3 位表示 runState,低 29 位表示workerCount

  • workerCount:存活的线程数

  • runState:线程池当前的运行状态

    • RUNNING: 接受新任务,处理等待队列中的任务。
    • SHUTDOWN: 不接受新任务,处理等待队列中的任务。
    • STOP: 不接受新任务,丢弃等待队列中的任务,中断正在运行的任务。
    • TIDYING: 当所有的任务已终止,workCount 为0,线程池会变为 TIDYING 状态。接着会执行terminated()函数。
    • TERMINATEDterminated()函数执行完成。

execute()

线程池处理任务的主要方法为execute()方法,下面看一下它的源码:

public void execute(Runnable command) {
   
    if (command == null) throw new NullPointerException();
    int c = ctl.get();
    //1. 如果当前工作线程数小于 corePoolSize
    if (workerCountOf(c) < corePoolSize) {
   
        //创建核心线程,并将 command 作为其绑定运行的第一个任务
        if (addWorker(command, true))
            return;
        c = ctl
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值