Avoid nested lock: A program that never request more than one lock cannot experience lock ordering deadlock
Timeout while attempting to lock
Example: ReentrantLock’s timed tryLock method
Lock Ordering: Always acquire locks in fixed global order
Starvation
Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress
usually when shared resources are made unavailable for long periods by “greedy” threads
The most commonly starved resource is CPU cycles
Examples:
inappropriate use of thread priorities
non-terminating loops/waits that do not release the lock
Livelock
Livelock is a form of liveness failure in which a thread, while not blocked, still cannot make progress because it keeps retrying an operation that will always fail
The solution to variety of livelock problems is to introduce randomness to the retry mechanism
Example:
When two stations in ethernet network try to send packet on shared carrier at the same time, packets collide. Retrying sending packets will again cause collision
Ethernet protocol includes exponential backoff after repeated collisions
In transactional messaging, if rollback happens due to any issue, the application puts the message back at the head of the queue
Thread issues
symptoms:
deadlocks
high CPU usage
diagnosis:
analyze thread dumps
Thread dump
Complete picture of all threads in your JVM and what they’re doing at the moment in time in which the “picture” was taken
It includes
stack trace for each running thread
locking information on which locks are held by which thread
which thread is BLOCKED and waiting to acquire which lock
deadlock information by calculating is-waiting-for graph for threads
tools to capture thread dump:
Java Mission Control (JMC)
Java Flight Record (JFR)
jcmd
jstack
jvisualvm
~5 thread dumps can be collected within 10 seconds to understand if they are waiting or blocked