美文网首页
Java线程池复用机制

Java线程池复用机制

作者: 周_0717 | 来源:发表于2019-10-23 19:02 被阅读0次

            线程复用的实质就是在Tread内的Runnable的run()方法中不断的获取任务,执行任务。

            线程池内将保留核心线程数量的死循环线程,其余线程在没有任务时在超时间后若再无任务则销毁(run()方法执行结束)。

    任务获取:

    ThreadPoolExecutor.getTask()

            这个方法内主要做3件事情:①检查线程池状态;②判断是否支持任务等待超时(timed);③跟据timed选择对应方法,从BlockingQueue中获取任务。

            在第三步中涉及到BlockingQueue.poll(long timeout, TimeUnit unit)和BlockingQueue#take()两个方法,两个方法都会尝试阻塞当前线程直到被唤醒,差别在于第一个方法在到达等待时间后会自动唤醒,第二个方法只能主动唤醒。

    BlockingQueue.poll(long timeout, TimeUnit unit)->Condition.awaitNanos(long nanosTimeout)->LockSupport.parkNanos(Object blocker, long nanos)->Unsafe.park(boolean b,long nanos)

    BlockingQueue.take()->Condition.await()->LockSupport.park(Object blocker)->Unsafe.park(boolean b,long nanos)

    执行任务:

    ThreadPoolExecutor.runWorker(Worker w)

            上述方法由Worker.run()调用,当上述方法执行完毕同时Worker.run()也将执行完毕,对应当Thread将被销毁。其中当Worker.firstTask为Worker创建时传入的任务,所以在复用时为null,因此当ThreadPoolExecutor.getTask()返回null,线程结束。

    唤醒线程:

            当通过ThreadPoolExecutor.execute(Runnable command)方法传入任务时,若存活线程数已超过核心线程数(少于则直接新建Worker),并且线程池已处于运行状态(否则尝试通过新建Worker启动线程池),此时会去调用BlockingQueue.offer(E e)方法,将任务放入BlockingQueue之中,并调用Condition.signal()方法唤醒一个之前阻塞的线程(LockSupport.unpark(Thread thread))。

    相关文章

      网友评论

          本文标题:Java线程池复用机制

          本文链接:https://www.haomeiwen.com/subject/zzukvctx.html