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
- Preemptive scheduling, the highest priority task executes first
- 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
Post a Comment