Java provides many ways to create and write multithreaded code.
There are 2 main types of threads in Java:
Platform Threads are native OS threads that Java wraps to provide a simple and consistent API for us to use (Java’s whole thing is write once run everywhere!). Comes with the resource expense of OS threads, but are great for CPU bound tasks.
Virtual Threads are ‘threads’ fully managed by the JVM, are extremely lightweight and good for I/O bound tasks but come with additional computational overhead. They share the same API as Platform Threads.
Java Thread States
Java provides its own abstraction over OS threads & their states.
This is then mapped to the actual platform thread & states.
Diagram of Native Thread Signalling Methods
Diagram of ObjectMonitor Signalling Methods
Diagram of Condition Signalling Methods
Condition signalling methods are used by Locks in the
java.util.concurrent.lockspackage
A thread can be in 1 of 7 states at any given time. 2 of which are just when it is created and when it is terminated. So that leaves us with 5 interesting states.
- Runnable
- Ready - Ready to be executed, waiting for its time on the CPU
- Running - Currently executing
- Waiting - Waits for some other thread to notify it to wake up and become runnable again
- Timed Waiting - Same as waiting, but it won’t wait forever, becoming runnable after a set amount of time
- Blocked - Waiting for control of a monitor
Multithreading Constructs
Java has many multithreading constructs to help us manage & coordinate threads and shared objects!
Synchronisation Constructs (Used for controlling access to shared objects)
- Monitor-based Synchronisation (Inherent Locks)
- Lock-based Synchronisation
- Volatile(talk about double lock singleton)
Threading Constructs
- Platform Threads
- Virtual Threads
- Executor Framework
Coordination Constructs
- CountDownLatch
- Semaphore
Concurrent Collections
- ConcurrentHashMap
- Collections.synchronizedList()
- BlockingQueue
Atomic Variables
- AtomicLong
- LongAdder
- AtomicReference