并发原理2





     







如果在一个整型 量上 维护 多种状 ,就一定需要 按位切割使用 量,
量切分成了两个部分,高 16 位表示 ,低 16 位表示写,划分方式如 5-8 所示。

当前同步状 值为 S ,写状 等于 S&0x0000FFFF (将高 16 位全部抹去), 态等 S>>>16 (无符号 0 右移 16 位)。当写状 增加 1 ,等于 S+1 ,当 增加 1 ,等于 S+(1<<16) ,也就是 S+0x00010000
根据状 的划分能得出一个推 S 不等于 0 ,当写状 S&0x0000FFFF )等于 0 则读
S>>>16 )大于 0 ,即 读锁 已被 取。














· 添加元素 1 列更新 head 点的 next 元素 1 点。又因 tail 点默 情况下等于 head 点,所以它 next 点都指向元素 1 点。
· 添加元素 2 列首先 置元素 1 点的 next 元素 2 点,然后更新 tail 点指向元素 2 点。
· 添加元素 3 tail 点的 next 元素 3 点。
· 添加元素 4 置元素 3 next 元素 4 点,然后将 tail 点指向元素 4 点。
主要做两件事情:
第一是 将入 队节 置成当前 列尾 点的下一个 点;
第二是更新 tail 点,如果 tail 点的 next 点不 空, 将入 队节 置成 tail 点,如果 tail 点的 next 空, 将入 队节 置成 tail next 点,所以 tail 点不 是尾 点。



队: 并不是每次出 队时 都更新 head 点,当 head 点里有元素 ,直接 head 点里的元素,而不会更新 head 点。只有当 head 点里没有元素 ,出 操作才会更新 head 点。
首先 头节 点的元素,然后判断 头节 点元素是否 空,如果 空,表示另外一个 线 程已 经进 行了一次出 操作将 该节 点的元素取走,如果不 空, 使用 CAS 的方式将 头节 点的引 用设置 null, 如果 CAS 成功, 直接返回 头节 点的元素,如果不成功,表示另外一个 线 程已 行了一次出 操作更新了 head 点, 致元素 生了 化,需要重新 头节 点。










线 程池的 理流程:
1 线 程池判断核心 线 程池里的 线 程是否都在 行任 。如果不是, 则创 建一个新的工作 线 程来 行任 。如果核心 线 程池里的 线 程都在 行任 则进 入下个流程。
2 线 程池判断工作 列是否已 经满 。如果工作 列没有 将新提交的任 个工作 列里。如果工作 了, 则进 入下个流程。
3 线 程池判断 线 程池的 线 程是否都 于工作状 。如果没有, 则创 建一个新的工作 线 行任 。如果已 经满 了, 给饱 和策略来 个任




ThreadPoolExecutor execute 方法分下面 4 种情况:
1 )如果当前运行的 线 程少于 corePoolSize 则创 建新 线 程来 行任 (注意, 一步 需要 取全局 )。
2 )如果运行的 线 程等于或多于 corePoolSize 将任 加入 BlockingQueue
3 )如果无法将任 加入 BlockingQueue 列已 ), 则创 建新的 线 程来 理任 (注意, 一步 需要 取全局 )。
4 )如果 建新 线 程将使当前运行的 线 程超出 maximumPoolSize ,任 将被拒 ,并 RejectedExecutionHandler.rejectedExecution() 方法。






线 程池中的 线 行任 分两种情况:
1 )在 execute() 方法中 建一个 线 ,会 让这 线 行当前任
2 线 行完 1 的任 后,会反复从 BlockingQueue 取任 行。







关闭线程池:
过调 线 程池的 shutdown shutdownNow 方法来关 闭线 程池。

原理:
历线 程池中的工作 线 程,然后逐个 线 程的 interrupt 方法来中断 线 程,所以无法响 中断的任 可能永 无法 止。

别:
shutdownNow 首先将 线 程池的状 态设 置成 STOP ,然后 尝试 停止所有的正在 行或 停任 线 程,并返回等待 行任 的列表。
shutdown 只是将 线 程池的状 态设 置成 SHUTDOWN ,然后中断所有没有正在 行任 线 程。

只要 用了 两个关 方法中的任意一个, isShutdown 方法就会返回 true
当所有的任 都已关 后,才表示 线 程池关 成功, 这时调 isTerminaed 方法会返回 true












FixedThreadPool
1 )如果当前运行的 线 程数少于 corePoolSize 则创 建新 线 程来 行任
2 )在 线 程池完成 预热 之后(当前运行的 线 程数等于 corePoolSize ),将任 加入 LinkedBlockingQueue
3 线 行完 1 中的任 后,会在循 中反复从 LinkedBlockingQueue 取任 行。


FixedThreadPool 使用无界 LinkedBlockingQueue 为线 程池的工作 列( 列的容量
Integer.MAX_VALUE )。使用无界 列作 工作 列会 对线 程池 来如下影响。
1 )当 线 程池中的 线 程数达到 corePoolSize 后,新任 将在无界 列中等待,因此 线 程池中 线 程数不会超 corePoolSize
2 )由于 1 ,使用无界 maximumPoolSize 将是一个无效参数。
3 )由于 1 2 ,使用无界 keepAliveTime 将是一个无效参数。
4 )由于使用无界 列,运行中的 FixedThreadPool (未 行方法 shutdown() shutdownNow() )不会拒 (不会 RejectedExecutionHandler.rejectedExecution 方法)。





SingleThreadExecutor
1 )如果当前运行的 线 程数少于 corePoolSize (即 线 程池中无运行的 线 程), 则创 建一个新 线 程来 行任
2 )在 线 程池完成 预热 之后(当前 线 程池中有一个运行的 线 程),将任 加入 Linked- BlockingQueue
3 线 行完 1 中的任 后,会在一个无限循 中反复从 LinkedBlockingQueue 取任 行。






CachedThreadPool
1 )首先 SynchronousQueue.offer Runnable task )。如果当前 maximumPool 中有空 闲线 正在 SynchronousQueue.poll keepAliveTime TimeUnit.NANOSECONDS ),那么主 线 offer 操作与空 闲线 行的 poll 操作配 成功,主 线 程把任 线 行, execute() 行完成;否 则执 行下面的步 2 )。
2 )当初始 maximumPool 空,或者 maximumPool 中当前没有空 闲线 ,将没有 线
SynchronousQueue.poll keepAliveTime TimeUnit.NANOSECONDS )。 种情况下,步 1 )将失 。此 CachedThreadPool 建一个新 线 行任 execute() 方法 行完成。
3 )在步 2 )中新 建的 线 程将任 务执 行完后,会 SynchronousQueue.poll keepAliveTime TimeUnit.NANOSECONDS )。 poll 操作会 闲线 程最多在 SynchronousQueue 中等待 60 。如果 60 内主 线 程提交了一个新任 (主 线 行步 1 )),那么 个空 闲线 程将 行主 线 程提交的新任 ;否 个空 闲线 程将 止。由于 60 秒的空 闲线 程会被 止,因此 长时间 保持空 CachedThreadPool 不会使用任何 源。


SynchronousQueue 是一个没有容量的阻塞 列。每个插入操作必 等待另一 线 程的 对应 移除操作,反之亦然。 CachedThreadPool 使用 SynchronousQueue ,把主 线 程提交的 务传递给 闲线 行。






ScheduledThreadPoolExecutor
1 )当 ScheduledThreadPoolExecutor scheduleAtFixedRate() 方法或者 scheduleWith-
FixedDelay() 方法 ,会向 ScheduledThreadPoolExecutor DelayQueue 添加一个 实现
RunnableScheduledFuture 接口的 ScheduledFutureTask
2 线 程池中的 线 程从 DelayQueue ScheduledFutureTask ,然后 行任




ScheduledThreadPoolExecutor 中的 线 1 行某个周期任 4 个步 骤:
1 线 1 DelayQueue 取已到期的 ScheduledFutureTask DelayQueue.take() )。到期任 是指 ScheduledFutureTask time 大于等于当前 时间
2 线 1 ScheduledFutureTask
3 线 1 修改 ScheduledFutureTask time 下次将要被 行的 时间
4 线 1 个修改 time 之后的 ScheduledFutureTask 放回 DelayQueue 中( Delay- Queue.add() )。




ScheduledThreadPoolExecutor 取任 程:
1 Lock
2 取周期任
· 如果 PriorityQueue 空,当前 线 程到 Condition 中等待;否 则执 行下面的 2.2
· 如果 PriorityQueue 元素的 time 时间 比当前 时间 大,到 Condition 中等待到 time 时间 ;否
则执 行下面的 2.3
· PriorityQueue 元素( 2.3.1 );如果 PriorityQueue 空, 则唤 醒在 Condition 中等待
的所有 线 程( 2.3.2 )。
3 Lock
ScheduledThreadPoolExecutor 在一个循 行步 2 ,直到 线 程从 PriorityQueue 取到一
个元素之后( 2.3.1 之后),才会退出无限循 束步 2 )。





ScheduledThreadPoolExecutor 添加任 程:
1 Lock
2 )添加任
· PriorityQueue 添加任
· 如果在上面 2.1 中添加的任 PriorityQueue 元素, 醒在 Condition 中等待的所有 线 程。
3 Lock





FutureTask:

FutureTask 于未启 或已启 态时 FutureTask.get() 方法将 线 程阻塞;
FutureTask 于已完成状 态时 FutureTask.get() 方法将 线 程立即返回 果或抛
出异常。
FutureTask 于未启 态时 FutureTask.cancel() 方法将 致此任 不会被 行;
FutureTask 于已启 态时 FutureTask.cancel true )方法将以中断 行此任 务线
的方式来 试图 停止任
FutureTask 于已启 态时 FutureTask.cancel false )方法将 不会 正在 行此任 线 生影响( 正在 行的任 运行完成);
FutureTask 于已完 成状 态时 FutureTask.cancel )方法将返回 false





开始 FutureTask 于未启 或已启 ,等待 列中已 3 线 程( A B C )在等待。此 线 D get() 方法将 线 D 也到等待 列中去等待。
线 E run() 方法 ,会 列中的第一个 线 A 线 A 醒后,首先把自己从 列中 除,然后 醒它的后 继线 B ,最后 线 A get() 方法返回。 线 B C D 重复 A 线 理流程。最 ,在 列中等待的所有 线 程都被 级联唤 醒并从 get() 方法返回。



























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值