代码清单 清单4.4基于监视器的机动车追踪器实现… .63 清单4.5类似于java.awt.Point的可变Point.… .64 清单4.6 Delegating VehicleTracker使用不可变的Point类 ...64 清单4.7将线程安全委托到ConcurrentHashMap. ..65 清单4.8返回l0cati0n集的静态拷贝,而非“现场(1ive)”的.66 清单4.9委托线程安全到多个底层的状态变量… 66 清单4.10 NumberRange类没有完整地保护它的不变约束(不要这样做) 67 清单4.11可变的线程安全P0it类..69 清单4.12安全发布底层状态的机动车追踪器.… 70 清单4.l3扩展的Vector包含一个“缺少即加入”方法… .72 清单4.14非线程安全的“缺少即加入”实现(不要这样做) .72 清单4.15使用客户端加锁实现的“缺少即加入”73 清单4.16使用组合(composition)实现“缺少即加入” .74 清单5.1操作Vector的复合操作可能导致混乱的结果. 80 清单5.2使用客户端加锁,对V伦ctor进行复合操作81 清单5.3迭代中可能抛出的ArrayIndexOutOfBoundsException. …81 清单5.4使用客户端加锁进行迭代.… .82 清单5.5用Iterator对List进行迭代 82 清单5.6迭代隐藏在字符串的拼接中(不要这样做) 84 清单5.7 ConcurrentMap接口.… .87 清单5.8桌面搜索应用程序中的生产者和消费者… 91 清单5.9开始桌面搜索… .92 清单5.10。恢复中断状态,避免掩盖中断.94 清单5.l1在时序测试中,使用CountDownLatch来启动和停止线程.… .96 清单5.12使用FutureTask预载稍后需要的数据 97 清单5.l3 Throwable强制转换为RuntimeException.. 98 清单5,14使用信号量来约束容器… 100 清单5.l5在一个细胞的自动系统中用CyclicBarrier协调计算 .102 清单5.16尝试使用HashMap和同步来初始化缓存… .103 清单5.l7用ConcurrentHashMap替换HashMap 105 清单5.18用FutureTask记录包装器… .06 清单5.l9 Memoizer最终实现. .108 清单5.20使用Mem0iZr为因式分解的servlet缓存结果.109 清单6.1顺序化的W伦b Server114 Java并发编程实践
代码清单 清单6.2 Web Server为每个请求启动-个新的线程 .…115 清单6.3 Executor接口. .117 清单6.4使用线程池的W伦b server..118 清单6.5为每个任务启动一个新线程的Executor.… .118 清单6.6 Executor在调用线程中同步地执行所有任务 .119 清单6.7 ExecutorService中的生命周期方法. .121 清单6.8支持关闭操作的Web Server …122 清单6.9 Timer的混乱行为. .124 清单6.10顺序地渲染页面元素 .125 清单6.11 Callable interface和Future interface .126 清单6.l2 ThreadPoolExecutor中newTaskFor的默认实现 126 清单6.I3使用Future等待图像下载 …128 清单6.l4 ExecutorCompletionService使用的QueueingFuture类 .129 清单6.I5使用CompletionService渲染可用的页面元素 130 清单6.16在预定时间内获取广告信息 .132 清单6.17在预定时间内请求旅游报价… 134 清单7.1使用volatile域保存取消状态… .137 清单7.2生成素数的程序运行一秒钟.137 清单7.3不可靠的取消把生产者置于阻塞的操作中(不要这样做) .139 清单7.4线程的中断方法. 139 清单7.5通过使用中断进行取消.… 清单7.6向调用者传递interruptedExceptic0n43 清单7.7不可取消的任务在退出前保存中断… ..144 清单7.8在外部线程中安排中断(不要这样做) …145 清单7.9在一个专门的线程中中断任务… …146 清单7.10通过Future来取消任务.… .147 清单7.Il在Thread中,通过覆写interrupt来封装非标准取消 .149 清单7.12用newTaskFor封装任务中非标准取消.… 151 清单7.13不支持关闭的生产者-消费者日志服务… …152 清单7.14向日志服务添加不可靠的关闭支持 .153 清单7.15向LogWriter添加可靠的取消 .154 清单7.16使用ExecutorService的日志服务 .155 清单7.17使用致命药丸来关闭… .156 清单7.l8 IndexingService的生产者线程 .157 Java并发编程实践
IV 代码清单 清单7.i9 IndexingService的消费者线程. 157 清单7.20使用私有Executor,将它的寿命限定于一次方法调用中.…158 清单7.21关闭之后,ExecutorService获取被取消的任务 159 清单7.22使用TrackingExecutorService为后续执行来保存未完成的任务 .160 清单7.23典型线程池的工作者线程的构建… 162 清单7.24 UncaughtExceptic0 Handler接口.163 清单7.25 UncaughtExceptionHandler将异常写入日志 .163 清单7.26注册关闭钩子来停止日志服务 …165 清单8.1在单线程化的Executor中死锁的任务(不要这样做)169 清单8.2 ThreadP00 lExecutor通用的构造函数172 清单83创建一个可变长的线程池,使用受限队列和“调用者运行”饱和策略。 .175 清单8.4使用Semaphore来遏制任务的提交 .176 清单8.5 ThreadFactory接 .176 清单8.6定制的线程工厂… .177 清单87自定义的线程基类… .178 清单8.8修改一个标准工厂方法创建的Executor.. .179 清单89扩展线程池以提供日志和计时功能 .180 清单8.10把顺序执行转换为并行执行.… …181 清单8.11把顺序递归转换为并行递归.… …182 清单8.12等待并行运算的结果. .182 清单8.13类似于“搬箱子”谜题的抽象, .183 清单814谜题解决者框架的链节点 …184 清单8.15顺序化的谜题解决者.… 185 清单8.16并发版的迷题解决者… .186 清单8.I7 ConcurrentPuzzleSolver使用可携带结果的闭锁 187 清单8.18能够感知任务不存在的解决者… .188 清单9.】使用Executor实现的SwingUtilities… .193 清单9.2构建于SwingUtilities之上的Executor …194 清单9.3简单的事件监听器.… …194 清单9.4将耗时任务绑定到可视化组件 .196 清单9.5提供用户反馈的耗时任务… .196 清单9.6取消耗时任务.… 197 清单9.7支持取消、完成和进度通知的后台任务类.199 清单9.8在BackgroundTask中启动一个耗时的、可取消的任务.… 200 Java并发编程实践
代码清单 V 清单10.1简单的锁顺序死锁(不要这样做) .207 清单10.2动态加锁顺序产生的死锁(不要这样做) 208 清单10.3制定锁的顺序来避免死锁..209 清单10.4开始一个循环,它在典型条件下制定死锁 .210 清单10.5协作对象间的锁顺序死锁(不要这样做) .212 清单10.6使用开放调用来避免协作对象之间的死锁 .214 清单10.7发生死锁后线程转储的部分信息. .217 清单11.1串行访问任务队列.… .227 清单11.2徒劳的同步(不要这样做) 230 清单11.3锁省略的候选程序 .231 清单11.4持有锁超过必要的时间… .233 清单11.5减少锁持续的时间 .234 清单11.6应当分拆锁的候选程序. .236 清单11.7使用分拆的锁重构ServerStatus… .236 清单11.8基于哈希的map中使用分离锁. 238 清单12.】利用Semaphore实现的有限缓存 249 清单12.2 BoundedBuffer的基本单元测试… .250 清单12.3测试阻塞与响应中断… 252 清单12.4适用于测试的中等品质的随机数生成器 .253 清单I2.5 BoundedBuffer的生产者-消费者测试程序 .255 清单12.6 PutTakeTest中的生产者和消费者类. 256 清单12.7测试资源泄漏… 258 清单12.8用于测试ThreadPoolExecutor的线程工厂. .258 清单12.9验证线程池扩展的测试方法 .259 清单12.l0使用Thread.yield产生更多的交替操作. .260 清单12.11基于关卡的计时器.… .261 清单12.12使用基于关卡的计时器进行测试… .262 清单12.13 TimedPutTakeTest的驱动程序. .262 清单13.】L0Ck接口.… .277 清单13.2使用ReentrantLock保护对象状态… .278 清单13.3使用tryLock避免锁顺序死锁 .280 清单13.4具有预定时间的锁. 281 清单13.5可中断的锁获取请求.… 281 清单13.6 ReadWriteL0ck接口 .286 Java并发编程实践
代码清单 清单13.7 用读写锁包装的Map… .288 清单14.1状态依赖的可阻塞行为的结构… .292 清单14.2有限缓存不同实现的基类 293 清单14.3如果有限缓存不满足先验条件,会停滞不前, .294 清单14.4调用GrumpyBoundedBuffer的客户端逻辑. .294 清单14.5有限缓存使用了拙劣的阻塞. .296 清单14.6有限缓存使用条件队列… .298 清单14.7状态依赖方法的规范式… .301 清单14.8在BoundedBuffer.put中使用“依据条件通知” 304 清单14.9使用wait和notifyA1实现可重关闭的阀门.… .305 清单14.10 Conditon接口… 307 清单14.11有限缓存使用显式的条件变量.… .309 清单14.12使用10ck实现的计数信号量.… .310 清单14,13AQS中获取和释放操作的规范式 312 清单14.14二元闭锁使用AbstractQueuedSynchronizer. .313 清单14.15非公平的ReentrantLock中tryAcquire的实现. .315 清单l4.16 Semaphore的tryAcquireShared和tryAcquireShared方法. 316 清单15.1模拟CAS操作… .322 清单15.2使用CAS实现的非阻塞计数器 .323 清单15.3使用CAS避免多元的不变约束… .326 清单15.4使用ReentrantL0ck实现随机数字生成器 327 清单15.5使用AtomicInteger实现随机数字生成器… 327 清单15.6使用Treiber算法(Treiber,1986)的非阻塞栈 .331 清单15.7 Michael--Scott非阻塞队列算法中的插入(Michael与Scot,1996).334 清单15.8在ConcurrentLinkedQueue中使用原子化的域更新器335 清单16.1没有充分同步的程序可以产生令人惊讶的结果(不要这样做).340 清单16.2 FutureTask的内部类示范了如何“驾驭”同步 .343 清单16.3不安全的惰性初始化(不要这样做)… .345 清单16.4线程安全的惰性初始化… 347 清单16.5主动初始化 347 清单16.6惰性初始化holder类技巧.… .348 清单167双检查锁反模式(不要这样做)… 349 清单16.8不可变对象的初始化安全性.… .350 Java并发编程实践