0% found this document useful (0 votes)
6 views

Multithreading Enhancement

The document provides an overview of Java Thread Groups, including their structure, advantages, and methods. It also discusses the Java concurrency framework, including the use of locks, ReentrantLock, and the Executor Framework for managing threads. Additionally, it covers Callable and Future for returning results from threads, as well as the ThreadLocal class for maintaining thread-specific variables.

Uploaded by

thandrasaiteja90
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Multithreading Enhancement

The document provides an overview of Java Thread Groups, including their structure, advantages, and methods. It also discusses the Java concurrency framework, including the use of locks, ReentrantLock, and the Executor Framework for managing threads. Additionally, it covers Callable and Future for returning results from threads, as well as the ThreadLocal class for maintaining thread-specific variables.

Uploaded by

thandrasaiteja90
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

Thread Group:

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.

6) System Group contains several system level threads like


(a) Finalizer
(b) Reference Handler
(c) Signal Dispatcher
(d) Attach Listener
O/P:
main
system

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

d) ThreadGroup getParent() returns parent group of current Thread


e) void list() It prints information abut ThreadGroup to the console.
f) int activeCount() returns number of active threads present in Thread Group
g) int activeGroupCount() it returns number of active groups present in current Thread Group
h) int enumerate(Thread[] t) to copy all active threads of this thread group into provided thread array, in
this case subThreadGroup threads will also be considered.
i) int enumerate(ThreadGroup[] g) to copy all active subThreadGroups of this thread group into
ThreadGroupArray
j) boolean isDaemon() to check weather the thread group is daemon or not
k) void setDaemon()
l) void interrupt() to interrupt all waiting or sleeping threads present in Thread Group
m) void destroy() to destroy thread Group and its sub thread groups

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

import java.util.concurrent package


Problems with traditional Synchronized keyword:
a. We are not having any flexibility to try for a lock without waiting.
b. There is no way to specify maximum waiting time for a Thread to get Lock so that Thread will
wait until getting the lock which may create Performance problem which may cause Deadlock.
c. If Thread releases a lock, then which waiting Thread will get that lock we are not having any
control on this.
d. There is no API to list out all waiting threads for a Lock.
e. Synchronized keyword compulsory we have to use either at Method level or within Method and
It is not possible to use across multiple methods.
To overcome above problems SUN introduced java.util.concurrent.locks package in v1.5. It also provides
several enhancements to programmer to provide more control on concurrency.

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.

3. Which of the following declaration are equal?


i. ReentrantLock l = new ReentrantLock();
ii. ReentrantLock l = new ReentrantLock(true);
iii. ReentrantLock l = new ReentrantLock(false);
iv. All the above.
Ans: 1st and 3rd.
4. ReentrantLock methods:
a. Void lock();
b. Boolean tryLock();
c. Boolean tryLock(long l, TimeUnit t);
d. Void lockInterruptibly();
e. Void unlock();
f. int getHoldCount(); Returns number of Holds on this lock by current Thread.
g. boolean isHeldByCurrentThread(); Returns true if and only if Lock is hold by current Thread.
h. int getQueueLength(); Returns number of Threads waiting for the Lock.
i. Collection getQueued Threads(); Returns collection of Threads which are waiting to get lock.
j. boolean hasQueuedThreads(); Returns true if any Thread waiting to get the lock.
k. boolean isLocked(); Returns true if lock is acquired by some Thread.
l. boolean isFair();Returns true if fairness policy set to True.
m. Thread getOwner(); Returns the Thread which acquired the lock.

O/P: true
true
0
1
true
false
false
Example: How to use ReentrantLock in place of Traditional Synchronized method.
O/P:

Good Morning: Dhoni //10 times


Good Morning: Yuvi //10 times
If we comment line 1 and 2 then Threads will be executed simultaneously, and we will get irregular output. If
we are not commenting line 1 and 2 then Threads will be executed one by one and we will get regular output.
5. DEMO program for TryLock Method.
O/P:
Thread1...Got lock and performing operations
Thread2...Unable to get lock hence performing alternate operations

6. DEMO 2 program for TryLock do while.


O/P:
Thread2...Got lock
Thread1...unable to get lock, let's try again
Thread1...unable to get lock, let's try again
Thread1...unable to get lock, let's try again
Thread2...releases lock
Thread1...Got lock
Thread1...releases lock

Java Thread Pools (Executor Framework)


Creating a new Thread for every job may create performance and memory problem. To overcome this,
we should go for Thread Pool. Thread Pool is pool of already created Threads ready to do our Job. Java
1.5v introduces Thread Pool Framework to Thread Pools. Thread Pool Framework also known as Executor
Framework.
We can create Thread Pool as: ExecutorService service = Executors.newFixedThreadPool(3);
We can submit runnable job using submit method. service.submit(job);
we can shutdown executor service by using shutdown method. service.shutdown();
Demo Program using ExecutorService:
O/P:
Shutting Down!
Job2...Job started by Thread: pool-1-thread-2
Job3...Job started by Thread: pool-1-thread-3
Job1...Job started by Thread: pool-1-thread-1
Job2...Job completed by Thread: pool-1-thread-2
Job1...Job completed by Thread: pool-1-thread-1
Job3...Job completed by Thread: pool-1-thread-3
Job5...Job started by Thread: pool-1-thread-2
Job4...Job started by Thread: pool-1-thread-1
Job6...Job started by Thread: pool-1-thread-3
Job5...Job completed by Thread: pool-1-thread-2
Job6...Job completed by Thread: pool-1-thread-3
Job4...Job completed by Thread: pool-1-thread-1
Note: While designing webs servers and application server we can use Thread Pool concept. By default,
most of the Thread Pool has 60 Threads.
Callable and Future
In the case of runnable job Thread won't return anything after completing job. If a Thread is required to
return some result after execution, then we should go for Callable. Callable interface method contains
only one method public Object call() throws Exception. If we submit Callable Object to Executor, then
after completing the job Thread returns Object of the type Future i.e. Future object can be used to
retrieve the result from Callable job.
CallableFutureDemo:

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

Runnable is present in java.lang package Callable is present in java.util.concurrent


package
Introduced in 1.0 version Introduced in 1.5 version

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.

Demo for ThreadLocal

O/P:
null
Durga
null

ThreadLocal Demo 2: Overriding of initialValue() method.

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:

Parent Thread Value: PP

Child Thread Value: CC

12. In the above program if we replace InheritableThreadLocal with ThreadLocal and if we override childValue
method or not the output will be:

Parent Thread Value: PP

Child Thread Value: null

13. In the above program if we are maintaining InheritableThreadLocal and if we are not overriding childValue
method then the output is:

Parent Thread Value: PP

Child Thread Value: PP

You might also like