Multithreading Enhancement
Multithreading Enhancement
1) Based on functionalities we can group threads into a single unit which is nothing but Thread Group i.e. Thread Group
contains group of threads.
2) In addition to threads Thread Group can also contain Sub Thread Group.
3) Main advantage of maintaining threads in the form of Thread Group is we can perform common operations easily.
For e.g. ThreadGroupA.stop()
4) Every Thread in java belongs to some group. Main Thread belongs to Main Group.
5) Every Thread group in Java is child group of System Group either directly or Indirectly. Hence System group acts as
root for all thread groups in Java.
7) Thread Group is a java class present in java.lang package and it is a direct child class of object.
First Second
System main
Group Group
8) Constructors:
a. ThreadGroup g = new ThreadGroup(String gName); Creates New Thread Group with specified
group name. Parent of this new Group is a Thread Group of currently executing Thread.
b. ThreadGroup g = new ThreadGroup(ThreadGroup pg, String gName); Creates new Thread
Group with specified Group Name, the parent of this new Thread Group is specified parent
group pg.
9) Important ThreadGroup class methods:
a) String getName(): returns name of the Thread Group
b) int getMaxPriority(): returns max priority of thread group
c) void setMaxPriority(int p): to set maximum priority of Thread Group, Default maxPriority is 10 only.
Threads in Thread Group that have already higher priority won’t be affected but for newly added
threads this Max Priority is applicable.
O/P:
5
5
3
O/P
2
1
java.lang.ThreadGroup[name=ParentGroup,maxpri=10]
Thread[ChildThread1,5,ParentGroup]
Thread[ChildThread2,5,ParentGroup]
java.lang.ThreadGroup[name=ChildGroup,maxpri=10]
0
1
java.lang.ThreadGroup[name=ParentGroup,maxpri=10]
java.lang.ThreadGroup[name=ChildGroup,maxpri=10]
10) WAP to display all active thread names belongs to System Group and its child group.
O/P:
Reference Handler isDaemon: true
Finalizer isDaemon: true
Signal Dispatcher isDaemon: true
Attach Listener isDaemon: true
main isDaemon: false
Lock (I)
Lock object is similar to implicit lock acquired by synchronized method or block. Lock implementation provide
more extensive operations than traditional implicit lock.
Important methods of Lock Interface:
a. void lock() We can use this method to acquire lock, if lock is already available than immediately
current thread will get that lock. If the lock is not already available, then it will wait until getting
the lock. It is exactly same behavior of traditional synchronized keyword.
b. boolean tryLock() To acquire the lock without waiting. If lock is available, then thread acquires
that lock and returns true if lock is not available then this method returns false ad continues its
execution without waiting. In this case thread will never be in Waiting State.
If(l.tryLock()) {
Perform Safe Operation.
} else {
Perform Alternative Operation }
c. boolean tryLock(long time, TimeUnit unit); If lock is available then thread will get the lock and
continue its execution. If the lock is not available, then Thread will wait until specified amount
of time still if the lock is not available then Thread can continue its execution. TimeUnit is an
Enum present in java.util.concurrent package. Enum TimeUnit {NANOSECONDS,
MICROSECONDS, MILISECONDS, SECONDS, MINUTES, HOURS, DAYS}.
If(l.tryLock(1000, TimeUnit.MILLISECONDS)))
d. void lockInterruptibly(); Acquires the lock if its available and returns immediately. If the lock is
not available, then it will wait while waiting If thread is interrupted then Thread won't get the
Lock.
e. void unlock(); To release the lock.
ReentrantLock(C)
1. ReentrantLock it is a implementation class of Lock Interface and it is a direct child class of object.
2. Reentrant means Thread can acquire same lock multiple times without any issues. Internally re-
entrant lock increments Thread personal count whenever we call l.lock() and decrements count value
whenever Thread calls l.unlock(). And lock will be released when count reaches 0.
a. ReentrantLock l = new ReentrantLock(); Creates an instance of ReentrantLock.
b. ReentrantLock l = new ReentrantLock(boolean fairness); Creates ReentrantLock with given
fairness policy. If fairness is true then longest waiting thread can acquire the lock if it is available
i.e. it follows First Come First Serve policy. If fairness is false, then which waiting Thread will get
the chance we can’t expect. Default fairness value is false.
O/P: true
true
0
1
true
false
false
Example: How to use ReentrantLock in place of Traditional Synchronized method.
O/P:
O/P:
pool-1-thread-1: is..responsible to find sum of first 10 numbers 55
pool-1-thread-2: is..responsible to find sum of first 20 numbers 210
pool-1-thread-3: is..responsible to find sum of first 30 numbers 465
pool-1-thread-1: is..responsible to find sum of first 40 numbers 820
pool-1-thread-2: is..responsible to find sum of first 50 numbers 1275
pool-1-thread-3: is..responsible to find sum of first 60 numbers 1830
Differences between Runnable and Callable
Runnable Callable
If a Thread is not required to return anything If a Thread required to return something after
after completing job then we should go for completing job, then we should go for Callable.
Runnable.
Runnable interface contains only one method Callable interface contains only one method call
run
Runnable job not required to return anything Callable job is required to return something
hence return type of run method is void hence return type of call method is Object
Within the run method if there’s is any chance Inside call method if there is any chance of
of raising checked exception compulsory we raising checked exception we are not required
should handle by using try catch. Because we to handle by using try catch because call
can’t use throws keyword for run method. method already throws Exception
Thread Local
1. ThreadLocal class provides Thread Local variables. ThreadLocal class maintains values per Thread
bases.
2. Each ThreadLocal object maintains separate value like userId, TransactionId etc. For each Thread
that access that ThreadLocal Object. Thread can access its local value and manipulate or even can
remove its value. In every part of the code which is executed by the Thread we can access its local
variable.
3. Example: Consider Servlet which invokes some business method. We have a requirement to
generate TransactionId for each request and we must pass this TransactionId to business method.
For this requirement we can use ThreadLocal to maintain separate TransactionId for every
Request i.e. for every Thread.
Note: ThreadLocal class introduced in 1.2 version and enhanced in 1.5 version
4. ThreadLocal can be associated with Thread Scope. Total code which is executed by Thread has access to
the corresponding Thread Local variables. Thread can access its own local variable and can’t access other
Threads local variables
5. Ones Thread entered in Dead State all its local variables are by default eligible for Garbage Collection.
6. Constructor: ThreadLocal tl = new ThreadLocal() creates ThreadLocal variable.
7. Methods:
a. Object get() Returns the value of Thread local variable associated with current Thread.
b. Object initialValue() returns initial value of Thread Local variables associated with current Thread.
Default implementation of this method returns null, to customize our own initial value we have to
override this method.
c. void set(Object newValue) to set a new value
d. void remove() to remove the value of Thread Local variable associated with current Thread. It is newly
added method in 1.5v. After removal if we are trying to access it will be reinitialised once again by
invoking its initial value method.
O/P:
null
Durga
null
O/P:
abc
Durga
abc
ThreadLocal Demo 3: Separate value in ThreadLocal for every Thread.
O/P:
Customer Thread-1 Executing with Customer Id: 1
Customer Thread-2 Executing with Customer Id: 2
Customer Thread-3 Executing with Customer Id: 3
Customer Thread-4 Executing with Customer Id: 4
Note: In the above program for every Customer Thread a separate CustomerId will be maintained by
ThreadLocal Object.
8. With respect to inheritance what is a behaviour of ThreadLocal: Parent Thread ThreadLocal variable by
default is not available to child Thread. If we want to make Parent Threads ThreadLocal variable value
available to child Thread, then we should go for InheritableThreadLocal class.
9. By default, Child Thread’s value is exactly same as Parent Threads value, but we can provide customized for
Child Thread by overriding childValue() method.
10. Constructor: InheritableThreadLocal itl = new InheritableThreadLocal();
11. Methods:
a. InheritableThreadLocal is the child class of ThreadLocal hence all methods present in
ThreadLocal by default available to InheritableThreadLocal. In addition to this method it
contains only one new method which is,
b. public Object childValue(Object parentValue).
O/P:
12. In the above program if we replace InheritableThreadLocal with ThreadLocal and if we override childValue
method or not the output will be:
13. In the above program if we are maintaining InheritableThreadLocal and if we are not overriding childValue
method then the output is: