logo资料库

Java.Concurrency.in.Practice.pdf

第1页 / 共357页
第2页 / 共357页
第3页 / 共357页
第4页 / 共357页
第5页 / 共357页
第6页 / 共357页
第7页 / 共357页
第8页 / 共357页
资料共357页,剩余部分请下载后查看
Contents
Listings
Preface
1 Introduction
1.1 A (very) brief history of concurrency
1.2 Benefits of threads
1.3 Risks of threads
1.4 Threads are everywhere
I: Fundamentals
2 Thread Safety
2.1 What is thread safety?
2.2 Atomicity
2.3 Locking
2.4 Guarding statewith locks
2.5 Liveness and performance
3 Sharing Objects
3.1 Visibility
3.2 Publication and escape
3.3 Thread confinement
3.4 Immutability
3.5 Safe publication
4 Composing Objects
4.1 Designing a thread-safe class
4.2 Instance confinement
4.3 Delegating thread safety
4.4 Adding functionality to existing thread-safe classes
4.5 Documenting synchronization policies
5 Building Blocks
5.1 Synchronized collections
5.2 Concurrent collections
5.3 Blocking queues and the producer-consumer pattern
5.4 Blocking and interruptible methods
5.5 Synchronizers
5.6 Building an efficient, scalable result cache
II: Structuring Concurrent Applications
6 Task Execution
6.1 Executing tasks in threads
6.2 The Executor framework
6.3 Finding exploitable parallelism
7 Cancellation and Shutdown
7.1 Task cancellation
7.2 Stopping a thread-based service
7.3 Handling abnormal thread termination
7.4 JVM shutdown
8 Applying Thread Pools
8.1 Implicit couplings between tasks and execution policies
8.2 Sizing thread pools
8.3 Configuring ThreadPoolExecutor
8.4 Extending ThreadPoolExecutor
8.5 Parallelizing recursive algorithms
9 GUI Applications
9.1 Why are GUIs single-threaded?
9.2 Short-running GUI tasks
9.3 Long-running GUI tasks
9.4 Shared data models
9.5 Other forms of single-threaded subsystems
III: Liveness, Performance, and Testing
10 Avoiding Liveness Hazards
10.1 Deadlock
10.2 Avoiding and diagnosing deadlocks
10.3 Other liveness hazards
11 Performance and Scalability
11.1 Thinking about performance
11.2 Amdahl’s law
11.3 Costs introduced by threads
11.4 Reducing lock contention
11.5 Example: Comparing Map performance
11.6 Reducing context switch overhead
12 Testing Concurrent Programs
12.1 Testing for correctness
12.2 Testing for performance
12.3 Avoiding performance testing pitfalls
12.4 Complementary testing approaches
IV: Advanced Topics
13 Explicit Locks
13.1 Lock and ReentrantLock
13.2 Performance considerations
13.3 Fairness
13.4 Choosing between synchronized and ReentrantLock
13.5 Read-write locks
14 Building Custom Synchronizers
14.1 Managing state dependence
14.2 Using condition queues
14.3 Explicit condition objects
14.4 Anatomy of a synchronizer
14.5 AbstractQueuedSynchronizer
14.6 AQS in java.util.concurrent synchronizer classes
15 Atomic Variables and Nonblocking Synchronization
15.1 Disadvantages of locking
15.2 Hardware support for concurrency
15.3 Atomic variable classes
15.4 Nonblocking algorithms
16 The Java Memory Model
16.1 What is a memory model, and why would I want one?
16.2 Publication
16.3 Initialization safety
A: Annotations for Concurrency
A.1 Class annotations
A.2 Field and method annotations
Java Concurrency in Practice Brian Goetz with Tim Peierls Joshua Bloch Joseph Bowbeer David Holmes and Doug Lea
Contents Listings Preface 1 Introduction 1.1 A (very) brief history of concurrency . 1.2 Benefits of threads . . . . . . . 1.3 Risks of threads . . . . . . . . . 1.4 Threads are everywhere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii xvii 1 1 3 5 9 Fundamentals I 2 Thread Safety 2.1 What is thread safety? . . . . . . 2.2 Atomicity . . . . . . . . . . 2.3 Locking . . . . . . . . . . . 2.4 Guarding state with locks . . . . 2.5 Liveness and performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Sharing Objects 3.1 Visibility . . . . . . 3.2 Publication and escape . . 3.3 Thread confinement . . . 3.4 . . . . Immutability . . . . 3.5 Safe publication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Composing Objects 4.1 Designing a thread-safe class . . . . . . 4.2 . . . . Instance confinement . . . . . . . 4.3 Delegating thread safety . . . . . . . . . 4.4 Adding functionality to existing thread-safe classes . . . . 4.5 Documenting synchronization policies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 15 . . 17 . . 19 . . 23 . . 27 . . 29 33 . . 33 . . 39 . . 42 . . 46 . . 49 55 . . 55 . . 58 . . 62 . . 71 . . 74 ix
x Contents 5 Building Blocks 5.1 Synchronized collections . . . . . 5.2 Concurrent collections . . . . . . 5.3 Blocking queues and the producer-consumer pattern . . . 5.4 Blocking and interruptible methods . . . . . . . . . 5.5 Synchronizers . . . . . . . . . . . . . . 5.6 Building an efficient, scalable result cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . II Structuring Concurrent Applications 6 Task Execution 6.1 Executing tasks in threads . . . . 6.2 The Executor framework . . . . 6.3 Finding exploitable parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Cancellation and Shutdown 7.1 Task cancellation . . . . . . . . 7.2 Stopping a thread-based service . . . . . . . 7.3 Handling abnormal thread termination . . . 7.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . JVM shutdown . . 8 Applying Thread Pools Implicit couplings between tasks and execution policies 8.1 8.2 Sizing thread pools . . . . . . . 8.3 Configuring ThreadPoolExecutor . . 8.4 Extending ThreadPoolExecutor . . . 8.5 Parallelizing recursive algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 GUI Applications 9.1 Why are GUIs single-threaded? . . . . . 9.2 Short-running GUI tasks . . . . . . . . . 9.3 Long-running GUI tasks . . . . . . . . . 9.4 Shared data models . . . . . . . . . . . . 9.5 Other forms of single-threaded subsystems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III Liveness, Performance, and Testing 10 Avoiding Liveness Hazards 10.1 Deadlock . . . . . 10.2 Avoiding and diagnosing deadlocks . 10.3 Other liveness hazards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Performance and Scalability 11.1 Thinking about performance . . 11.2 Amdahl’s law . . . . . . . 11.3 Costs introduced by threads . . . 11.4 Reducing lock contention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 . . 79 . . 84 . . 87 . . 92 . . 94 . . 101 111 113 . . 113 . . 117 . . 123 135 . . 135 . . 150 . . 161 . . 164 167 . . 167 . . 170 . . 171 . . 179 . . 181 189 . . 189 . . 192 . . 195 . . 198 . . 202 203 205 . . 205 . . 215 . . 218 221 . . 221 . . 225 . . 229 . . 232
Contents 11.5 Example: Comparing Map performance . . . 11.6 Reducing context switch overhead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Testing Concurrent Programs 12.1 Testing for correctness . . . . . . 12.2 Testing for performance . . . . . 12.3 Avoiding performance testing pitfalls . . . . 12.4 Complementary testing approaches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IV Advanced Topics 13 Explicit Locks 13.1 Lock and ReentrantLock . . . . . . . . . 13.2 Performance considerations . . . . . . . 13.3 Fairness . . . . . . . . . . . 13.4 Choosing between synchronized and ReentrantLock . . . 13.5 Read-write locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Building Custom Synchronizers 14.1 Managing state dependence . . . . . . . 14.2 Using condition queues . . . . . . . . . 14.3 Explicit condition objects . . . . . . . . . 14.4 Anatomy of a synchronizer . . . . . . . 14.5 AbstractQueuedSynchronizer . . . . . 14.6 AQS in java.util.concurrent synchronizer classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Atomic Variables and Nonblocking Synchronization 15.1 Disadvantages of locking . . . . . . . 15.2 Hardware support for concurrency . . 15.3 Atomic variable classes . . . . . 15.4 Nonblocking algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 The Java Memory Model 16.1 What is a memory model, and why would I want one? . . 16.2 Publication . . . . . . . . . 16.3 Initialization safety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A Annotations for Concurrency . . . . A.1 Class annotations . . . . . A.2 Field and method annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi . . 242 . . 243 247 . . 248 . . 260 . . 266 . . 270 275 277 . . 277 . . 282 . . 283 . . 285 . . 286 291 . . 291 . . 298 . . 306 . . 308 . . 311 . . 314 319 . . 319 . . 321 . . 324 . . 329 337 . . 337 . . 344 . . 349 353 . . 353 . . 353
Listings 1 Bad way to sort a list. Don’t do this. . 2 Less than optimal way to sort a list. . 1.1 Non-thread-safe sequence generator. 1.2 Thread-safe sequence generator. . . . 2.1 A stateless servlet. . . . . . . . 2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 2.4 2.5 . . . . . . . . . . . . . . . . . . . . . . . . Servlet that counts requests without the necessary synchroniza- tion. Don’t do this. . . . . Race condition in lazy initialization. Don’t do this. Servlet that counts requests using AtomicLong. . . Servlet that attempts to cache its last result without adequate atomicity. Don’t do this. Servlet that caches last result, but with unnacceptably poor con- currency. Don’t do this. . . . . . . 2.7 Code that would deadlock if intrinsic locks were not reentrant. . 2.8 . . . . Servlet that caches its last request and result. . . . . 3.1 . . . . Sharing variables without synchronization. Don’t do this. 3.2 Non-thread-safe mutable integer holder. . . . . . . . . 3.3 . . . . . . . . 3.4 . . . . . . . . 3.5 . . . . . . . . 3.6 Allowing internal mutable state to escape. Don’t do this. . . . . . 3.7 . 3.8 Using a factory method to prevent the this reference from escap- Thread-safe mutable integer holder. . Counting sheep. . . . . . . Publishing an object. Implicitly allowing the this reference to escape. Don’t do this. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ing during construction. Thread confinement of local primitive and reference variables. 3.9 3.10 Using ThreadLocal to ensure thread confinement. . . . . 3.11 Immutable class built out of mutable underlying objects. 3.12 Immutable holder for caching a number and its factors. 3.13 Caching the last result using a volatile reference to an immutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . holder object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.14 Publishing an object without adequate synchronization. Don’t do . . xix . . xx 6 . . 7 . . . . 18 . . 19 . . 21 . . 23 . . 24 . . 26 . . 27 . . 31 . . 34 . . 36 . . 36 . . 39 . . 40 . . 40 . . 41 . . 42 . . 44 . . 45 . . 47 . . 49 . . 50 . . 50 . . 51 . . 56 . . 59 . . 61 this. . . . . . . . . . . . . . . . . . . . . . . . 3.15 Class at risk of failure if not properly published. 4.1 4.2 Using confinement to ensure thread safety. 4.3 Guarding state with a private lock. . . . . Simple thread-safe counter using the Java monitor pattern. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
Listings xiii Immutable Point class used by DelegatingVehicleTracker. 4.4 Monitor-based vehicle tracker implementation. . . . . . . 4.5 Mutable point class similar to java.awt.Point. . . . . . . 4.6 . . 4.7 Delegating thread safety to a ConcurrentHashMap. . . . . 4.8 Returning a static copy of the location set instead of a “live” one. 4.9 Delegating thread safety to multiple underlying state variables. 4.10 Number range class that does not sufficiently protect its invari- . . . . . . . . . . . . . . 63 . . 64 . . 64 . . 65 . 66 . . 66 . . . . . . . . . . . . . . . . . . . . . . . . ants. Don’t do this. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 . . . . . 69 4.11 Thread-safe mutable point class. . . . . . 70 4.12 Vehicle tracker that safely publishes underlying state. 4.13 Extending Vector to have a put-if-absent method. . . 72 4.14 Non-thread-safe attempt to implement put-if-absent. Don’t do this. . 72 4.15 Implementing put-if-absent with client-side locking. . . 73 4.16 Implementing put-if-absent using composition. . . . . 74 5.1 Compound actions on a Vector that may produce confusing results. 80 . . 81 5.2 Compound actions on Vector using client-side locking. . . . . 5.3 . . 81 Iteration that may throw ArrayIndexOutOfBoundsException. . . . . 82 5.4 . . . . . . . . Iteration with client-side locking. . . 82 5.5 . . . . Iterating a List with an Iterator. . . . . . . 84 5.6 . . . Iteration hidden within string concatenation. Don’t do this. 5.7 . . 87 . . . . ConcurrentMap interface. . . . . 5.8 . . 91 Producer and consumer tasks in a desktop search application. . . . 92 5.9 . . . . Starting the desktop search. 5.10 Restoring the interrupted status so as not to swallow the interrupt. 94 5.11 Using CountDownLatch for starting and stopping threads in timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tests. . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.12 Using FutureTask to preload data that is needed later. 5.13 Coercing an unchecked Throwable to a RuntimeException. 5.14 Using Semaphore to bound a collection. 5.15 Coordinating computation in a cellular automaton with Cyclic- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Barrier. . . . . . . . . . . . . . Sequential web server. . . . . . . 5.16 Initial cache attempt using HashMap and synchronization. 5.17 Replacing HashMap with ConcurrentHashMap. . . . . 5.18 Memoizing wrapper using FutureTask. . . . . . . 5.19 Final implementation of Memoizer. . . . . . . . . 5.20 Factorizing servlet that caches results using Memoizer. . . 6.1 . . . . 6.2 Web server that starts a new thread for each request. . . . 6.3 . . . . . . . . 6.4 Web server using a thread pool. . . . . 6.5 . . . . 6.6 6.7 6.8 Web server with shutdown support. 6.9 6.10 Rendering page elements sequentially. 6.11 Callable and Future interfaces. . . . . . . . . . Class illustrating confusing Timer behavior. . . . . . . . Executor that starts a new thread for each task. Executor that executes tasks synchronously in the calling thread. Lifecycle methods in ExecutorService. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Executor interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 . . 97 . . 98 . . 100 . . 102 . . 103 . . 105 . . 106 . . 108 . . 109 . . 114 . . 115 . . 117 . . 118 . . 118 . 119 . . 121 . . 122 . . 124 . . 125 . . 126
xiv Listings 6.12 Default implementation of newTaskFor in ThreadPoolExecutor. 6.13 Waiting for image download with Future. . . . . . 6.14 QueueingFuture class used by ExecutorCompletionService. . . 6.15 Using CompletionService to render page elements as they be- . . . . . . . . . . . . . . . . . . . come available. . . . . . . 6.16 Fetching an advertisement with a time budget. . . 6.17 Requesting travel quotes under a time budget. . . 7.1 Using a volatile field to hold cancellation state. . 7.2 Generating a second’s worth of prime numbers. . 7.3 Unreliable cancellation that can leave producers stuck in a block- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Propagating InterruptedException to callers. ing operation. Don’t do this. . . . . . . Interruption methods in Thread. . . . . . . . . 7.4 . . . . 7.5 Using interruption for cancellation. . . . . 7.6 . . . . 7.7 Noncancelable task that restores interruption before exit. 7.8 7.9 7.10 Cancelling a task using Future. 7.11 Encapsulating nonstandard cancellation in a Thread by overriding Scheduling an interrupt on a borrowed thread. Don’t do this. Interrupting a task in a dedicated thread. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 . . 128 . . 129 . . 130 . . 132 . . 134 . . 137 . . 137 . . 139 . . 139 . . 141 . . 143 . . 144 . . 145 . . 146 . . 147 call. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . interrupt. . . . . . . . . . . . 149 7.12 Encapsulating nonstandard cancellation in a task with newTaskFor. 151 7.13 Producer-consumer logging service with no shutdown support. . . 152 7.14 Unreliable way to add shutdown support to the logging service. . . 153 . . 154 7.15 Adding reliable cancellation to LogWriter. . . . . . 7.16 Logging service that uses an ExecutorService. . . . . 155 7.17 Shutdown with poison pill. . . . . . 156 . . . . . . . . . 157 7.18 Producer thread for IndexingService. . . . . 7.19 Consumer thread for IndexingService. . . 157 . . . . 7.20 Using a private Executor whose lifetime is bounded by a method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 7.21 ExecutorService that keeps track of cancelled tasks after shutdown.159 7.22 Using TrackingExecutorService to save unfinished tasks for later . . 160 . . 162 . . 163 . . 163 . . 165 Task that deadlocks in a single-threaded Executor. Don’t do this. . . 169 . . 172 . . . . . . . . . . . . 7.23 Typical thread-pool worker thread structure. . . . . . . . 7.24 UncaughtExceptionHandler interface. . . . . . . . . . . . 7.25 UncaughtExceptionHandler that logs the exception. . . . 7.26 Registering a shutdown hook to stop the logging service. 8.1 8.2 General constructor for ThreadPoolExecutor. . . . 8.3 Creating a fixed-sized thread pool with a bounded queue and the caller-runs saturation policy. . . . . . . . . . . . . . . . . . . . . execution. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ThreadFactory interface. Custom thread factory. . Custom thread base class. 8.4 Using a Semaphore to throttle task submission. 8.5 8.6 8.7 8.8 Modifying an Executor created with the standard factories. 8.9 Thread pool extended with logging and timing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 . . 176 . . 176 . . 177 . . 178 . . 179 . . 180
Listings xv . . . . . . . . . . . . . . . . . . . . . 8.10 Transforming sequential execution into parallel execution. . . 181 8.11 Transforming sequential tail-recursion into parallelized recursion. . 182 . . 182 8.12 Waiting for results to be calculated in parallel. . . . . . . 183 8.13 Abstraction for puzzles like the “sliding blocks puzzle”. . 8.14 Link node for the puzzle solver framework. . . 184 . . . . . . 185 8.15 Sequential puzzle solver. . . . . . . . . . . . . . 186 8.16 Concurrent version of puzzle solver. . . . . . . . . 8.17 Result-bearing latch used by ConcurrentPuzzleSolver. . . 187 . 8.18 Solver that recognizes when no solution exists. . . 188 . . . . 9.1 . . 193 . . . . . 194 9.2 . . . . . . 194 9.3 . . . . 9.4 . . 196 . . . . . 196 9.5 . . . . 9.6 . . 197 . . . . 9.7 . . Implementing SwingUtilities using an Executor. . . . . Executor built atop SwingUtilities. . . . . Simple event listener. . . . . . . . . Binding a long-running task to a visual component. . . . . Long-running task with user feedback. . . . Cancelling a long-running task. . . . . . . . . Background task class supporting cancellation, completion notifi- . . . . cation, and progress notification. Initiating a long-running, cancellable task with BackgroundTask. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 9.8 . 200 10.1 Simple lock-ordering deadlock. Don’t do this. . . 207 . . . 10.2 Dynamic lock-ordering deadlock. Don’t do this. . . 208 . . 10.3 Inducing a lock ordering to avoid deadlock. . . . . . . 209 10.4 Driver loop that induces deadlock under typical conditions. . . 210 10.5 Lock-ordering deadlock between cooperating objects. Don’t do this. 212 10.6 Using open calls to avoiding deadlock between cooperating objects. 214 . . 217 10.7 Portion of thread dump after deadlock. . . . . . . . . 11.1 Serialized access to a task queue. . . 227 . . . . . . . . . . 230 11.2 Synchronization that has no effect. Don’t do this. . . . . . . . . . . 231 11.3 Candidate for lock elision. . . . . . . . . . . . . . . . . . 233 11.4 Holding a lock longer than necessary. . . . . . . . . . . . 11.5 Reducing lock duration. . . 234 . . . . . . . . . . . . . . . . . 236 11.6 Candidate for lock splitting. . . . . . . . . . . . . . . . . . 236 11.7 ServerStatus refactored to use split locks. . . . . . . . . . . 238 11.8 Hash-based map using lock striping. . . . . . . . . . . . . 12.1 Bounded buffer using Semaphore. . . 249 . . . . . . . . . . . . . . . . 250 12.2 Basic unit tests for BoundedBuffer. . . . . . . . . . . . . . . . 252 12.3 Testing blocking and responsiveness to interruption. . . . . . . . . . 253 12.4 Medium-quality random number generator suitable for testing. 12.5 Producer-consumer test program for BoundedBuffer. . . 255 . . . . . . 12.6 Producer and consumer classes used in PutTakeTest. . . 256 . . . . . . . . 258 12.7 Testing for resource leaks. . . . . . . . . . . 258 12.8 Thread factory for testing ThreadPoolExecutor. . . . . . . . . 12.9 Test method to verify thread pool expansion. . . 259 . . . . . . . . 12.10 Using Thread.yield to generate more interleavings. . . . . . 260 . . . . . . 261 12.11 Barrier-based timer. . . . . . . . . . . 262 12.12 Testing with a barrier-based timer. . . . . . . . . 12.13 Driver program for TimedPutTakeTest. . . 262 . . . . . . . . 13.1 Lock interface. . . 277 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
分享到:
收藏