Java Concurrency Recap: Thread and Synchronization(Locks)

Overview

This is a simple Java Concurrency topics Recap including Thread and Synchronization(Locks) mechanism, i.e., Runnable, Thread, synchronization, Lock dead lock

Java Concurrency Recap: Thread and Synchronization(Locks)

Java has different mechanisms to support concurrency. These mechanisms include A) Thread  which you can imagine as Cars on the road, which are the real things you operate on to achieve concurrency. Cars are for you to use to drive as Threads are for you to do concurrency); B) Synchronization(Locks) and you can imagine this as the traffic lights and the police man who control the traffic regulation and keep the cars in the correct position so the whole traffic (Your application or Your program) would be going or working smoothly and correctly.

1) How to create the threads

  1. Implements the Runnable interface, and create a thread instance by feeding the runnable instance into the thread, and then call run()
  2. Extend the Thread class and then create an instance, call run()

By using the Runnable interface, it would be more efficient and more flexible because extending a Thread class would make this class unable to extend other classes and it could also be possible that the clients may only be interested in the Runnable rather than other features (fields and other methods) so extending other parts from Thread would be unnecessary.

Remarks: ExecutorService might preferred way to execute thread than using Thread with the run() method

2) How to manage threads (Concurrency Control)

  1. Use “synchronized” keyword: more common than Lock, and it applies to methods and code blocks and restrict threads from executing the code simultaneously on the SAME OBJECT. Note the following differences for synchronized on X.class vs this (From Stackoverflow)
    • The snippet synchronized(X.class) uses the class instance as a monitor. As there is only one class instance (the object representing the class metadata at runtime) one thread can be in this block.
    • With synchronized(this) the block is guarded by the instance. For every instance only one thread may enter the block.
    • synchronized(X.class) is used to make sure that there is exactly one Thread in the block.
    • synchronized(this) ensures that there is exactly one thread per instance.
    • Whether this makes the actual code in the block thread-safe depends on the implementation. If mutate only state of the instance synchronized(this) is enough.
  2. If we need more granular control, we might want t use Lock in Java: Lock lock = new ReentrantLock(); lock.lock(); {Critical Section} lock.unlock(); So only a single thread could enter the critical section.
  3. How to create a dead lock, here is my way: There are two Threads A and B, Two locks C and D,  and 4 time points t1 < t2 < t3 < t4, at time point t1, A get to hold lock C and successfully executes to time point t3 at which A want to get access to lock D, at the same time, what happens to B is, at time point t2, B successfully get to hold lock D and executes to time point t4 at which B wants to get access to lock C, so A is waiting for lock D at time t3 but B is holding D and D will not be released because B is waiting for A at time t4. They are deadlocked! The most common way to avoid dead lock is to avoid such circularly waiting.
  •  volatile: used to flush value of variable into main memory from cache so other tasks could see the change immediately the try to read this variable, atomicity, visibility
  • By making tasks depend on a non-task object, we eliminate the potential race condition where task here means the thread.
  • Thread Local Storage

Summary

This is a simple Java Concurrency topics Recap including Thread and Synchronization(Locks) mechanism, i.e., Runnable, Thread, synchronization, Lock dead lock

Written on January 27, 2015