All about Java Multi Threading

Terms used in Multi-threading

Daemon threads
The daemon threads are basically the low priority threads that provides the background support to the user threads. Thread class setDaemon(true) can be used to create daemon thread in java. We need to call this method before calling start() method else it will throw IllegalThreadStateException.

Analyze a deadlock
To analyze a deadlock, we need to look at the java thread dump of the application, we need to look out for the threads with state as BLOCKED and then the resources it’s waiting to lock, every resource has a unique ID using which we can find which thread is already holding the lock on the object.
Avoid Nested Locks, Lock Only What is Required and Avoid waiting indefinitely are common ways to avoid deadlock situation, read this post to learn how to analyze deadlock in java with sample program.

Ways to achieve Synchronization

There are several ways to achieve thread safety in java – synchronization, atomic concurrent classes, implementing concurrent Lock interface, using volatile keyword, using immutable classes and Thread safe classes. 

Types of Scheduling
  1. Preemptive scheduling, the highest priority task executes first
  2. Time slicing, a task executes for a predefined slice of time


Concurrent classes

1.    CountDownLatch  & CyclicBarrier
A java.util.concurrent.CountDownLatch is a concurrency construct that allows one or more threads to wait for a given set of operations to complete.
http://tutorials.jenkov.com/java-util-concurrent/countdownlatch.html
The java.util.concurrent.CyclicBarrier class is a synchronization mechanism that can synchronize threads progressing through some algorithm. In other words, it is a barrier that all threads must wait at, until all threads reach it, before any of the threads can continue.
http://tutorials.jenkov.com/java-util-concurrent/cyclicbarrier.html
1)    CyclicBarrier is resulable, CountDownLatch is not.
2)    Both CyclicBarrier and CountDownLatch wait for fixed number of threads.
3)    CountDownLatch is advanceable but CyclicBarrier is not.

2.    Executors Framework

The Executor framework is a framework for standardizing invocation, scheduling, execution, and control of asynchronous tasks according to a set of execution policies.
Creating a lot many threads with no bounds to the maximum threshold can cause application to run out of heap memory. So, creating a ThreadPool is a better solution as a finite number of threads can be pooled and reused. Executors framework facilitate process of creating Thread pools in java. 
3.    BlockingQueue
BlockingQueue implementations are thread-safe. All queuing methods are atomic in nature and use internal locks or other forms of concurrency control.
4.    Callable Interface
Callable interface is similar to Runnable interface but it can return any Object and able to throw Exception.
Callable interface use Generic to define the return type of Object. Executors class provide useful methods to execute Callable in a thread pool. Since callable tasks run in parallel, we have to wait for the returned Object. Callable tasks return java.util.concurrent.Future object. Using Future we can find out the status of the Callable task and get the returned Object. It provides get() method that can wait for the Callable to finish and then return the result.

Atomic operation
Atomic operations are performed in a single unit of task without interference from other operations. Atomic operations are necessity in multi-threaded environment to avoid data inconsistency.
int++ is not an atomic operation. So by the time one threads read it’s value and increment it by one, other thread has read the older value leading to wrong result.
To solve this issue, we will have to make sure that increment operation on count is atomic, we can do that using Synchronization but Java 5 java.util.concurrent.atomic provides wrapper classes for int and long that can be used to achieve this atomically without usage of Synchronization.
Replace Integer count++; with AtomicInteger count.incrementAndGet()
When we use volatile keyword with a variable, all the threads read it’s value directly from the memory and don’t cache it.
Lock interface provide more extensive locking operations than can be obtained using synchronized methods and statements.
·         To make a thread responsive to interruption while waiting on a Lock object.
·         it’s possible to try to acquire the lock, but return immediately or after a timeout if the lock can’t be acquired
·         Acquire and release locks in different scopes, and in different orders


Comments