1. Basic thread management
2. Thread synchronization mechanisms
3. Thread creation and management
delegation with executors
4. Fork/Join farmework to enhance the
performance of your application
5. Data structures for concurrent programs
6. Adapting the default behavior of some
concurrency classes to your needs
7. Testing Java concurrency applications
In this chapter, we will cover:
● Creating and running a thread
● Getting and setting thread information
● Interrupting a thread
● Controlling the interruption of a thread
● Sleeping and resuming a thread
● Waiting for the finalization of a thread
● Creating and running a daemon thread
● Processing uncontrolled exceptions in a
● Using local thread variables
● Grouping threads into a group
● Processing uncontrolled exceptions in a
group of threads
● Creating threads through a factory
Creating and running a thread
Threads are Objects. We have two ways of
creating a thread in Java:
● Extending the Thread class and overriding
the run() method
● Building a class that implements the
Runnable interface and then creating an
object of the Thread class passing the
Runnable object as a parameter
Creates and runs 10 threads.
Each thread calculates and prints the
mutiplication table of a number between 1 and
You can implement a class that extends
Thread class and overrides the run()
method of this class.
Call the start() method to have a new
Getting and setting thread
The Thread class saves some infomation
attributes that can help us to identify a thread:
● ID: A unique identifier for each Thread.
● Proiority: The priority of the Thread
value ∈ [1, 10] (low-->high)
Not recommended to change, but you can use
if you want.
● Status: Thread can be in one of these six
states (new, runnable, blocked,
waiting, time watiing,
You can’t modify the ID and stauts of a thread.
Develop a program that establishes the name
and priority for 10 threads, and then show
information about their status until they finish.
The Thread class has another method to
check whether Thread has been interrupted or
Difference: isInterrupted() and
● interrupted() is static and checks the
● isInterrupted() is an instance method
which checks the Thread object that it is
The second one doesn’t change the
interrupted attribute value, but the first one
set it to false.
think about these...
● (1) and (3)
● (1) and (4)
● (2) and (3)
● (2) and (4)
Controlling the interruption of a
InterruptedException: A better
mechanism to control the interruption of the
Detect and throw this exception and catch in
the run() method.
We will implement Thread that looks for files
with a determined name in a
folder and in all its subfolders to show how to
use the InterruptedException exception
to control the interruption of a thread.
When Thread is sleeping and is interrupted,
the method throws an
exception immediately and doesn't wait until the
sleeping time finishes.
Waiting for the finalization of a
We can use the join() method of the Thread
When we call this method using a thread
object, it suspends the execution of the calling
thread until the object called finishes its
public final void join()
Waits for this thread to die.
join() ==> join(0)
InterruptedException - if any thread has
interrupted the current thread. The interrupted
status of the current thread is cleared when this
exception is thrown.
Waits at most millis milliseconds for this thread
to die. A timeout of 0 means to wait forever.
join(long milliseconds, long nanos)
If the object thread1 has the code, thread1.
join(1000), the thread2 suspends its
execution until one of these two conditions is
● thread1 finishes its execution
● 1000 milliseconds have been passed
When one of these two conditions is true, the
join() method returns.
Creating and running a daemon
Java has a special kind of thread called
What is daemon thread?
● Very low priority.
● Only executes when no other thread of the
same program is running.
● JVM ends the program finishing these
threads, when daemon threads are the only
threads running in a program.
What does daemon thread used for...
Normally used as service providers for normal
Usually have an infinite loop that waits for the
service request or performs the tasks of the
They can’t do important jobs.
Example: The java garbage collector.
Developing an example with two threads:
● One user thread that writes events on a
● One daemon thread that cleans the queue,
removing the events which were generated
more than 10 seconds age.
How it works...
If you analyze the output of one execution of
the program, you can see how the queue
to grow until it has 30 events and then, its size
will vary between 27 and 30 events until the
end of the execution.
Find out the reason...
● ArrayDeque: Not thread-safe
● We can use LinkedBlockingDeque…
Deque<Event> deque = new
● You only call the setDaemon() method
before you call the start() method. Once
the thread is running, you can’t modify its
● Use isDaemon() method to check if a
thread is a daemon thread or a user thread.
Difference between Daemon and
Non Daemon thread in Java :
● JVM doesn't wait for any daemon thread to
finish before existing.
● Daemon Thread are treated differently than
User Thread when JVM terminates, finally
blocks are not called, Stacks are not
unwounded and JVM just exits.
Processing uncontrolled exceptions
in a thread
There are two kinds of exceptions in Java:
● Checked exceptions
● Unchecked exceptions
Exceptions in run() method:
● Checked exception:
We have to catch and treat them, because
the run() method doesn't accept a throws
● Unchecked exception:
A mechanism to catch and treat the
The default behaviour is to write the stack
trace in the console and exit the program.
We will learn this mechanism using an
How it works...
If the thread has not got an uncaught exception
handler, the JVM prints the stack trace in the
console and exits the program.
Establishes an exception handler for all the
Thread objects in the application.
When an uncaught exception is
thrown in Thread...
JVM looks for…
1. The uncaught exception handler of the
2. The uncaught exception handler for
ThreadGroup of the Thread objects.
3. The default uncaught exception handler.
The JVM writes the stack trace of the exception
Using local thread variables
One of the most critical aspects of a concurrent
application is shared data.
If you change an attribute in a thread, all the
threads will be affected by this change.
The Java Concurrency API provides a clean
mechanism called thread-local variables with a
very good performance.
We will develop a program that has the
problem and another program using the thread-
local variables mechanism.
● protected T initialValue()
● public T get()
● public void set(T value)
● public void remove()
It provides inheritance of values for threads
created from a thread.
You can override the childValue() method
that is called to initialize the value of the child
thread in the thread-local variable.
Grouping threads into a group
ThreadGroup: The threads of a group as a
A threadGroup object can be formed by
Thread objects and by another ThreadGroup
A tree structure of threads.
Simulating a search...
We will have 5 threads sleeping during a
random period of time, when one of them
finishes, we are going to interrupt the rest.
Creating threads through a factory
The factory pattern in OO is a creational
Develop an object whose creating other objects
of one or servel classes.
Instead of using the new operator.
Centralize the creation of objects.
● It's easy to change the class of the objects
created or the way we create these objects.
● It's easy to limit the creation of objects for
limited resources. For example, we can only
have n objects of a type.
● It's easy to generate statistical data about
the creation of the objects.
Java provides the ThreadFactory interface to
implement a Thread Object factory.
Well will implement a ThreadFactory
interface to create Thread objects with a
personalized name while we save statistics of
the Thread objects created.