Overview of Concurrency
Threads in Java
- Usage of class Thread
- Usage of interface Runnable
- Life-cycle methods
- How to interrupt, but not stop, a thread
Critical Sections
- The Bank problem
- What is a critical section
- What is a mutex lock
- Riboe's conditions for critical sections
- Using synchronized blocks and methods in Java
Race Conditions
- The MailBox problem
- What is condition/event synchronization
- The minimal amount of code to safely send a message from one thread to another
- Using wait and notify
- Understanding the difference between notify and notifyAll
- A few words about monitor semantics
- Possible livelock with careless usage of notify
Deadlocks
- What is a resource
- Starvation
- What is a deadlock
- Coffman's conditions for deadlocks
- Preventing deadlocks
- Dealing with deadlocks
- How the JVM detect deadlocks
Uni-Directional Message-Passing
- Design of a blocking message queue
- Thread safe queues in the Java API
- Design and implementation of MessageQueue and MessageThread
Bi-Directional Message-Passing
- What is rendezvous
- Implementation of rendezvous
- What is a future and how can it be used
- Realizing N --> 1 and 1 --> N communication patterns
Thread Pools
- The Executors framework
- Callable and Executor
- ExecutorService
- Adapting the pool size to the number of processing units
- Typical tasks for thread pools
Fork-Join
- What is fork-join concurrency
- Designing a fork-join task
- Using a fork-join pool and schedule many tasks
- Typical tasks for fork-join pools
Atomic Data-Types
- What is an atomic type
- AtomicInteger and friends
Lock and Synchronization Classes
- How to use read-write locks
- How to use dedicated lock and synchronization objects
- Barriers, latches, phasers and other fun synchronizators
- Semaphores
- Optimistic locks