文档章节

线程池ThreadPoolExecutor的内部类Worker的感想和思考

萧默
 萧默
发布于 2019/12/15 10:33
字数 893
阅读 15
收藏 0
JDK

Worker依然是一个Runnable,封装了一个创建自己的原因对象,就是firstTask变量,和自己将要执行的所在线程thread变量。

thread成员变量可以直接被外部类ThreadPoolExecutor所获得,当调用addWorker方法时,会获得这个thread对象,从而启动成为真正的线程。然后,这个线程开始执行Worker的run方法,run方法直接调用其外部类ThreadPoolExecutor的方法runWorker,这个runWorker因为要前后会执行提供给子类自己完善的模板方法beforeExecute和afterExecute,也许这个是为什么worker要直接执行外部类方法的一个原因吧。但我猜想,不是这么简单。

首先runWorker会把产生创建自己的原因的任务给先执行了,然后,开始while((task == getTask()) != null)的无线循环下去,而getTask方法依然还是外部类ThreadPoolExecutor的方法,原来,runWorker的调用,用意是将代码的执行流程带到自己的方法流程上。

getTask()方法,是个无线循环方式从workQueue尝试拉取任务来执行,但为什么要做那么多额外的工作呢?一般人写拉取阻塞队列的对象,无非就是无限循环的workQueue.poll()吗?为什么jdk里面的实现里面有这么多代码呢?

因为有keepalive参数的设置,所以,顶多改写成workQueue.poll(keepalive,TimeUnit.SECONDS)。

我们想一想,能够让getTask方法返回的原因就哪些?

1.超过keepalive的时间,返回空任务,此时runWorker方法结束调用。

2.线程池被关闭,此时,响应中断。

原来就一个参数可以控制是否使用keepalive参数,这个参数是allowCoreThreadTimeOut,其他额外的代码应该就是为了这个参数服务的。其实为了正确的停止线程池发出的shutdown命令的。

我们来看shutdown方法,

首先加锁? 

然后调用checkShutdownAccess方法,尝试检测是否具有停止线程的权限和访问线程的权限,若存在,则执行下面的一个方法调用,否则,直接就解锁返回方法调用了。

然后调用advanceRunState修改线程池的状态位shutown

然后调用interruptIdleWorkers方法,传递参数为false,也就是并非只打断一个线程,开始打断所有空闲的worker线程,此时若有空闲的线程,应该是阻塞在workQueue.poll或workQueue.take方法调用处,

Worker对象的实现AbstractQueuedSynchronizer类,意在是自己能够具有类似锁的能力,其实就是标识自己是否是空闲线程,当一个工作线程获得任务,那么我们让它在执行自己的业务代码之前加锁,其他线程判断它是否忙碌,只要调用tryLock就可以知道,如果tryLock返回true,那么就说明这个线程是空闲线程,若返回false,则说明不是,因为工作线程没有执行完自己的业务代码。为什么直接继承这个AbstractQueuedSynchronizer类,而不是使用其他重入锁,因为就是想获得互斥的能力,而不想具有重入的能力。

线程的执行方式,以来线程的停止方式。

© 著作权归作者所有

萧默
粉丝 0
博文 43
码字总数 19380
作品 0
杭州
程序员
私信 提问
JDK线程池源码分析之ThreadPoolExecutor

前言 JDK中为我们提供了一个并发线程框架,它是的我们可以在有异步任务或大量并发任务需要执行时可以使用它提供的线程池,大大方便了我们使用线程,同时将我们从创建、管理线程的繁琐任务中解...

Justlearn
2017/04/24
0
0
【JDK源码分析】线程池ThreadPoolExecutor原理解析

前言 一般情况下使用线程池都是通过Executors的工厂方法得到的,这些工厂方法又基本上是调用的ThreadPoolExecutor的构造器。也就是说常用到的线程池基本用到的是ThreadPoolExecutor。ThreadP...

还是搬砖踏实
2018/08/05
0
0
Java线程池ThreadPoolExecutor使用与解析

概述 JDK提供了一个工具类Executors来非常方便的创建线程池,下面主要通过一个示例来分析Java线程池的实现原理。 使用 例子里面使用了Executors.newFixedThreadPool(2)创建了一个固定只有2个...

gaob2001
2019/03/15
21
0
ThreadPoolExecutor源码详解

我之前一篇文章谈到了ThreadPoolExecutor的作用(http://my.oschina.net/xionghui/blog/494004),这篇文章介绍下它的原理,并根据原理分析下它的实现源码。 我们先来查看一下ThreadPoolExe...

xionghuiCoder
2015/08/19
3.3K
3
Java 线程池 实现原理与源码深度解析

正文 史上最清晰的线程池源码分析 鼎鼎大名的线程池。不需要多说!!!!! 这篇博客深入分析 Java 中线程池的实现。 总览 下图是 java 线程池几个相关类的继承结构: 先简单说说这个继承结构,E...

编辑之路
2019/01/13
115
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 宇宙银河乱弹英雄传 —— @FalconChen

1Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @巴拉迪维 :Axxis的单曲《Only God Knows》 最近只听摇滚,挖了好多以前没听过的歌,蛮好。#今日歌曲推荐# 《Only God Knows》- Axxis 手机...

小小编辑
今天
137
1
Safari Date() 函数对日期时间字符串(yyyy-MM-dd HH:mm:ss) 提示NaN的问题

今天发现一个奇怪的问题,在iPhone使用 safari 选择定时发布文章到OSC,选择时间后提示不是合法的时间,判断时间的代码如下: var d = new Date('2020-01-23 23:15'); if (isNaN(d)) {...

FalconChen
昨天
124
0
ActiveMQ学习之通讯协议

一、支持的通讯协议 ActiveMQ支持的client-broker通讯协议有:TCP、NIO、UDP、SSL、HTTP(S)、VM 其中配置Transport Connector的文件在ActiveMQ安装目录的conf/activemq.xml中的<TransportCon...

冥焱
昨天
91
0
应急广播户户通平台

一、平台概述 应急广播户户通平台为软硬一体化广播服务解决方案。实现了应急广播、视音频及图片文字信息、调频及数字广播FM、天气预报信息接收功能,以及视音频播放、智能机器人、电子日历等...

neocean
昨天
133
0
如何为Apache 2.2启用mod_rewrite

我已经在我的Vista机器上安装了新的Apache 2.2,一切正常,除了mod重写。 我没有注释 LoadModule rewrite_module modules/mod_rewrite.s 但是我的重写规则都没有,即使是简单的重写规则 Re...

javail
昨天
53
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部