array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 JAVA高并发编程--第三章读书笔记 - 爱码网

 

中断响应JAVA高并发编程--第三章读书笔记

 

P74的代码,一开始死锁形成的原因是t1占用lock1请求lock2,t2占用lock2请求lock1,而后来死锁得以释放是因为

49行T2中断后,不再等待lock1,同时释放lock2。T1可以继续运行,而t2放弃任务直接退出。

如果这里是synchronize关键字形成的死锁,则无法像这里使用lock形成的死锁那么好处理。

 

 

注:

lockinterruptibly()方法比较特殊,当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够通过interrupt方法完成响应中断,即中断线程的等待状态。也就是说,当两个线程同时通过lock.lockinterruputibly()去获取某个锁时,假如此时线程A获取到了锁,而线程B只有等待,那么对线程调用threadB.interrupt()方法能够中断线程B的等待过程。

注意:当一个线程获取了锁之后,是不会被interrupt()方法中断的

因此当通过lockinterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的

而用synchronized修饰的话,当一个线程处于等待某个锁的状态,是无法被中断的,只有一直等待下去。(源于CSDN)

 

锁申请等待限时

JAVA高并发编程--第三章读书笔记

公平锁

两个线程同时申请某个锁时,系统会从这两个线程中随机选一个并向其提供锁。这是非公平锁。

公平锁实现成本较大,一般不使用,

JAVA高并发编程--第三章读书笔记

第二行代码,往构造函数输入true,则可构建公平锁。

 

Condition条件

JAVA高并发编程--第三章读书笔记

第24行主线程unlock了重入锁,这样condition.signal()后,t1才能重新获得锁。

剩下的工具类看书吧,范例和文字都很简洁。

信号量

读写锁

倒计数器

循环栅栏

 

LockSupport

他和suspend和resume的区别在于,suspend和resume,先suspend后resume是没问题的,但是先resume后suspend有可能导致系统判定线程是runnable的,但线程其实是挂起的。

而LockSupport为每一个线程准备了一个许可,许可可用,park的时候就立即返回且将许可变为不可用。许可不可用,就阻塞。Unpack可以将许可变为可用。

       所以P95的代码,如果t1先在run方法中碰到park,这时许可不可用(我个人认为许可默认不可用),t1阻塞。如果不unpark,t1就一直阻塞并持有synchronize上的锁,那么t2是没有办法执行run方法的,而如果t1 unpark了,那么park方法就会因为许可可用而立即返回(立即执行),run方法就结束了,放出锁给t2,t2继续执行run方法。如果先Unpark,那么许可变为可用,执行run中的park时,park立即返回并将许可变为不可用,此时t1执行完run,t2获得锁继续执行run方法,故unpark在park之前或之后执行都一样。Park方法执行后会明确该线程状态是waiting的。

 

 

 

Guava和RateLimiter限流

 

线程池

JDK提供一套Executor框架作为线程池,

JAVA高并发编程--第三章读书笔记

JAVA高并发编程--第三章读书笔记

FixedThreadPool的示例:

JAVA高并发编程--第三章读书笔记

JAVA高并发编程--第三章读书笔记

17行代码创建内有5个线程的线程池,18行代码提交十个任务。

 

ScheduleThreadPool

示例:

JAVA高并发编程--第三章读书笔记

scheduleAtFixedRate

JAVA高并发编程--第三章读书笔记

示例中的代码传入的参数是0,2

指的是初始延时时间为零,此时任务开始,后一个任务将在0+2时执行,再后一个任务会在0+2*2时执行。

JAVA高并发编程--第三章读书笔记

如果是scheduleWithFixedDelay,则任务开始于初始延时时间,前一个任务结束时到下一个任务开始时,其中的时间间隔是long delay。

 

FixedThreadPool,SingleThreadExecutor和CacheThreadPool都利用了ThreadPoolExecutor来实现。

JAVA高并发编程--第三章读书笔记

ThreadPoolExecutor构造函数:

JAVA高并发编程--第三章读书笔记

JAVA高并发编程--第三章读书笔记

其中的workQueue:

JAVA高并发编程--第三章读书笔记

JAVA高并发编程--第三章读书笔记

 

 

拒绝策略

JAVA高并发编程--第三章读书笔记

这四个都是RejectedExecutorHandler接口的实现类。

 

Fork/Join框架

 

一些并发容器

相关文章: