Shared Model-Immutability
Shared Model-Immutability
Immutability Design
Immutability is a design principle where classes and their attributes are marked as final, ensuring that the attributes are read-only and cannot be modified.
Protective Copy
Protective copying involves creating copy objects to prevent sharing. This technique safeguards the content of arrays from being altered by other classes.
Flyweight Pattern
The Flyweight pattern emphasizes data sharing to minimize resource wastage. Instead of using protective copying, it aims to wrap frequently used data in shared objects.
Thread Safety: Java Memory Model (JMM)
Java Memory Model (JMM)
JMM defines main memory and working memory concepts, which correspond to CPU registers, caches, hardware memory, and CPU instruction optimizations. It ensures thread safety through concepts like atomicity, visibility, and ordering.
Atomicity
Atomicity guarantees that instructions are not influenced by thread context switches.
Visibility
Visibility ensures that instructions are not affected by CPU caching. You can use volatile to address visibility issues, making variables read directly from main memory.
Ordering
Ordering ensures that instructions are not affected by CPU instruction parallelization. To prevent instruction reordering, volatile can be used.
Thread Safety: Shared Models and Strategies
Shared Models
- Double-Checked Locking: Lazy instantiation with potential issues. Adding
volatileto the instance variable can resolve ordering problems. - Happens-Before: Rules that govern shared variable writes and reads, ensuring visibility and ordering.
- Read-Write Locks: Use cases for ReentrantReadWriteLock to enhance read concurrency while ensuring write exclusivity.
Thread Pools
ThreadPoolExecutor
ThreadPoolExecutor manages thread pools with states represented by an atomic variable (ctl) combining thread pool status and the number of threads.
ThreadPool Types
- newFixedThreadPool: Core and maximum threads are equal, suitable for tasks with known quantities.
- newCachedThreadPool: Core threads are 0, and maximum threads are Integer.MAX_VALUE, useful for tasks with short execution times.
- newSingleThreadExecutor: Sequential execution with a single thread.
- Custom Sizing: Adjust thread pool size based on CPU characteristics (e.g., CPU-bound vs. I/O-bound tasks).
Synchronization and Locking
AQS and ReentrantLock
AbstractQueuedSynchronizer (AQS) forms the basis for various synchronization primitives like ReentrantLock.
ReentrantLock Principles
- Non-fair locking implementation.
- Reentrant and interruptible locking modes.
- Supports condition variables.
- Shared implementation for read and write locks.
StampedLock
StampedLock, introduced in JDK 8, enhances read performance and supports optimistic reads. It uses “stamps” for synchronization.
Semaphore
Semaphores limit concurrent access to shared resources by controlling the number of threads allowed.
CountdownLatch and CyclicBarrier
CountdownLatch
CountdownLatch is used for thread synchronization, allowing threads to wait until a specified count reaches zero.
CyclicBarrier
CyclicBarrier coordinates threads by waiting for a specific number of threads to reach a barrier point before proceeding.
These concepts and strategies are essential for understanding thread safety and efficient concurrent programming in Java.