8/10/2019 M9 - Concurrency
1/40
Java
Module 9Concurrency
8/10/2019 M9 - Concurrency
2/40
2
Module Objectives
At the end of this module, participants will beable to:
Define the concept behind multi-threaded
applications
Create and control a multi-threaded application
8/10/2019 M9 - Concurrency
3/40
3
What is a Thread?
The term thread is short for thread of execution. A thread of execution is a sequence of instructions that is
executed one after another in its own call stack.
A thread executes instructions one at a time; the thread must
execute and finish the current instruction before moving on to
the next one.
From a developers perspective an application begins with 1
main thread that is usually started when thepublic static void
main(String[]) method is called.
8/10/2019 M9 - Concurrency
4/40
4
Statements are executed one at a time in the appropriatesequence depending on program flow.
One statement must finish execution before the next
statement can begin execution.
** Refer to SingleThreadWorker.java sample code
Single Thread Application (Diagram)
Worker
Curly
Created
Worker
Larry
Created
Worker
Moe
Created
Main
Thread
Ends
Application
Starts
Application
Ends
Main
Thread
Starts
Application Timeline
Worker
Curly
work(5)
Worker
Larry
work(5)
Worker
Moe
work(5)
8/10/2019 M9 - Concurrency
5/40
5
Concurrency
An application that is able to manage and coordinate multipletasks simultaneously or pseudo-simultaneously is called a
concurrent application.
Concurrency allows tasks to execute without waiting for the
other tasks to complete through a defined system of task
switching and scheduling.
A concurrent application is able to make better of use system
resources as it allows a tasks to make use of a resource that
may not be currently required by other tasks.
8/10/2019 M9 - Concurrency
6/40
6
Concurrency in Java
The most common way of implementing concurrency in a Javaapplication is through multiple threads.
Java by nature is multithreaded as all applications have several
background threads running in addition to the application code.
Each thread can create and start new threads.
The application terminates when the main thread and all
application created threads finish execution.
8/10/2019 M9 - Concurrency
7/407
Task Scheduling
Multiple threaded applications make use of thread switching andscheduling that allow multiple threads to make use of the
systems resources.
The actual algorithm for thread scheduling depends heavily on
the native operating system.
8/10/2019 M9 - Concurrency
8/408
Creating a Thread
An instance of the Thread class is needed to create and executethe new thread.
The code that the thread will execute can be defined through
either of the following:
Subclass the Thread class, override its public void run() method
Pass a Runnable object with an overridden public void run() method
to a Thread objects constructor
Call the Thread instances start() method to start the thread.
The code inside the run() method will be executed in its own
thread only if it is invoked using the start() method.
8/10/2019 M9 - Concurrency
9/409
When each MultiThreadWorker is started, it is executed in its ownthread, independent of the main thread.
This application has a total of 4 application threads: the main thread,
Curly thread, Larry thread and Moe thread.
** Refer to the MultiThreadWorker.java and MultiThreadLauncher.java sample code
Concurrency in Java (Diagram)
Curly
Starts
Larry
Starts
Moe
Starts
Main Thread
Ends
Moe
Ends
Application
Starts
Application
Ends
Main Thread
Starts
Curly
Ends
Curly works()
Larry works()
Moe works()
Application Life Time
Larry
Ends
8/10/2019 M9 - Concurrency
10/40
10
When a thread is created (but not started) it is at its create state.
When a thread invokes its start() method, it is now alive and is
placed in a runnable poolwhere all living threads wait their turn
to be run by the scheduler.
Thread Lifecycle
start()
New
New Runnable
8/10/2019 M9 - Concurrency
11/40
11
Thread Lifecycle (cont.)
The thread scheduler chooses a thread to execute from thethreads in the pool.
If another thread is chosen by the scheduler to execute before it
finishes, it goes back to the thread pool to await its turn again.
start()New Runnable Running
Schedulersets thethread toexecute
start()New Runnable Running
Scheduler setsthe thread to
execute
Scheduler chose another
runnable thread to execute
8/10/2019 M9 - Concurrency
12/40
12
Thread Lifecycle (cont.)
A thread may also block, wait or sleep while it was runningcausing it to enter a state where it is alive, but not runnable.
blocking: thread is waiting for a resource or an event.
waiting: thread is waiting for a signal from another thread.
sleep: the thread pauses itself for a specified duration.
start()New Runnable Running
Scheduler sets
the thread toexecute
Scheduler chose anotherrunnable thread to execute
block/
wait/sleep Blocking/waiting/sleep event
occurs
8/10/2019 M9 - Concurrency
13/40
13
Thread Lifecycle (cont.)
After a thread recovers from blocking, waiting or sleeping, itreturns to a Runnable state and waits in the pool to be executed
again.
start()
New Runnable Running
Scheduler setsthe thread to
execute
Scheduler chose anotherrunnable thread to execute
block/
wait/sleep Blocking/waiting/sleep event
occursThread recoversfrom
block/wait/sleep
8/10/2019 M9 - Concurrency
14/40
14
Thread Lifecycle (cont.)
If the thread finishes its execution by exiting its run() method, itis now a dead thread.
A dead thread cannot be brought back to life.
Deadstart()
New Runnable Running
Scheduler setsthe thread to
execute
Scheduler chose anotherrunnable thread to execute
block/
wait/sleep Blocking/waiting/sleep event
occursThread recovers
fromblock/wait/sleep
run() method
finishes
8/10/2019 M9 - Concurrency
15/40
15
Managing Threads
Basic Concepts Setting Thread Priority
Pausing Threads
Yielding a Thread
Joining a Thread Synchronizing Threads
8/10/2019 M9 - Concurrency
16/40
16
Basic Concepts
The application often has very little control in determining thebehavior of threads.
The application can influence the behavior of threads, but it
cannot have direct control.
A variety of factors are taken in by the thread scheduler in
determining which threads to execute, such as:
Availability of a CPU resources
Activity or inactivity of the thread
Designated priority
8/10/2019 M9 - Concurrency
17/40
17
Basic Concepts (cont.)
Application logic should never be designed to rely on predictingthread behavior.
After a thread is caused to block, wait or sleep, it returns to the
runnable state not the running state, making it impossible to
determine exactly when it will run again.
8/10/2019 M9 - Concurrency
18/40
18
Thread Priority
Normally a thread with higher priority will be scheduled to runbefore a thread with a lower priority, but this is not always the
case.
The scheduler may choose to run a lower priority thread for
efficiency reasons or if the thread itself causes the scheduler to
choose another thread. Implementation of thread priority varies depending on the
underlying platform, and thus should never be considered as a
factor when designing application logic.
8/10/2019 M9 - Concurrency
19/40
19
Setting Thread Priority
A Java thread inherits its default priority from the thread thatcreated it.
A thread can set its priority by calling its setPriority(int) method.
Valid values are defined as integers ranging between
Thread.MIN_PRIORITY and Thread.MAX_PRIORITY.
8/10/2019 M9 - Concurrency
20/40
20
Pausing a Thread
Calling Thread.sleep(duration) stops the current thread fromexecuting and places it in a state that prevents it from being
chosen by the scheduler.
Putting a thread to sleep guarantees that it will not run and will
not be eligible run for the specified duration.
When a thread wakes up after being put to sleep, it will beplaced in a Runnable state, and NOT the Running state.
8/10/2019 M9 - Concurrency
21/40
21
Example: Pausing a Thread
In the initial example, the Worker thread is made to pauseregularly during every iteration of the loop.
public void work(int taskCount){
for(int task = 0; task < taskCount ; task++){
System.out.println("Worker " + name + " doing task " + task);
try{
Thread.sleep(delay);
}
catch(InterruptedException ex){
System.err.println("Unexpected interruption of thread " +Thread.currentThread().getName());
}
}
}
Pausing a running thread allows other threads a chance toexecute.
8/10/2019 M9 - Concurrency
22/40
22
Yielding a Thread
The Thread.yield() method is intended to cause the currentthread to go back to a runnable state, ideally allowing the
scheduler to choose another thread to execute.
Yielding a thread does NOT guarantee that another thread will
be chosen to run; there is still a chance that the thread that
yielded will be chosen again.
8/10/2019 M9 - Concurrency
23/40
23
Joining a Thread
A thread can be told to join a thread at the end by calling thejoin() method of another live thread object.
This guarantees that the current thread will enter a blocked state
while the thread object it joined finishes.
After the joined thread finishes execution, the current thread
returns to a runnable state.
8/10/2019 M9 - Concurrency
24/40
24
Joining a Thread (cont.)
Application
Starts
Application
Ends
Application Life Time
Main Thread
Starts
Larry
StartsLoop Starts
i == 3
Thread blocks
LarryEnds
Thread
resumes Main Thread
The main thread will block until it joins the Larry thread when the
Larry thread finishes.
** Refer to the JoinThreadSample.java sample code
8/10/2019 M9 - Concurrency
25/40
25
Thread Interference
Threads communicate and pass data to each other byaccessing the fields of objects that they share.
Because of this shared nature it is possible for threads to
interfere with each other with regards to the objects that they
share.
Thread interfering with one another with regards to sharedobjects can result in inconsistent views on the data that they
share.
** Refer to the Incrementer.java, IncrementerSample.java, andThreadIncrementer.java sample code
8/10/2019 M9 - Concurrency
26/40
26
Synchronization and Locks
Synchronization is one of the tools to avoid thread interference andmemory consistency errors.
Sections of code can be synchronized so that only one thread at a
time can execute that section of code.
Synchronization relies on the concept of a lock that a Thread has
to acquire before being allowed to execute a section of code.
When a thread invokes a synchronized method, it automatically
acquires the Intrinsic Lock for that methods object and releases it
when the method returns.
Intrinsic Locks can only be owned by one thread at a time.
8/10/2019 M9 - Concurrency
27/40
27
Synchronized Methods
A synchronized method guards an entire method from multiplethread access.
public synchronized void increment(){
if(x == 10)
return false;
x ++;return true;
}
Synchronized instance methods relies on a lock associated to
the current instance.
Synchronized static methods relies on a class lock.
** Refer to the Incrementer.java, IncrementerSample.java, and
ThreadIncrementer.java sample code
8/10/2019 M9 - Concurrency
28/40
28
Synchronized Blocks
Greater granularity can be achieved by synchronizing onlycritical blocks inside a method.
This allows only certain sections of code inside a method to beguarded, and also allows more flexibility in specifying what lockto acquire.
public void increment(){
System.out.println(I am not a critical section of code);
synchronized(this){ //Can also specify another object instance if required
if(x == 10)
return false;
x ++;
}
return true;
}
8/10/2019 M9 - Concurrency
29/40
29
To address the limitations of Intrinsic Locks, Explicit locks in Java5 can be implemented to provide more flexibility.
Features of Explicit Locks:
Ability to interrupt a thread waiting for a specific lock.
A thread can give a timeout value for attempting to acquire the lock;
Read/write locks are supportedmultiple threads can hold a locksimultaneously for read only access.
The traditional wait/notify metaphor is extended to allow conditions.
Support for fairness by following the first-in-first-out order if more thanone thread is waiting for a lock.
The ability to lock beyond the scope of a block: for example, onemethod can pass a lock object to another thread;
Ability to query the status and properties of a specific lockprogrammatically (i.e., number of threads waiting to acquire the lock).
Explicit Locks
8/10/2019 M9 - Concurrency
30/40
30
Coordinating Threads
Threads will often need to coordinate with one another toaccomplish their tasks.
One of the more common coordination scenarios is a thread that
needs to finish a section of code before another thread can
proceed.
One way to accomplish this coordination is by making thedependent thread wait until it has been notified by the other
thread that it can proceed.
8/10/2019 M9 - Concurrency
31/40
31
Coordinating Threads (cont.)
Objects have a wait/notify mechanism that allows threads tocoordinate with each other.
The wait() method of an object tells the current thread acting on
the object to block.
The thread waiting on the object will continue once the objects
notify() method has been executed by another thread.
The wait() and notify() methods of an object can only be
executed by a thread that has exclusive lock on the object.
** Refer to the AnnoyingPassenger.java, AnnoyedDriver.java, andPollingSample.java sample code
8/10/2019 M9 - Concurrency
32/40
Creating and Executing Threads
In J2SE 5.0, the preferred means of creating a multithreaded
application is to implement the Runnableinterface (package java.lang)
and use built-in methods and classes to create Threads that execute
the Runnables.
The Runnable interface declares a single method named run.
Runnables are executed by an object of a class that implements the
Executorinterface (package java.util.concurrent).
This interface declares a single method named execute.
An Executor object typically creates and manages a group of threads
called a thread pool. These threads execute the Runnable objects
passed to the execute method.
8/10/2019 M9 - Concurrency
33/40
Creating and Executing Threads (cont)
The Executor assigns each Runnable to one of the availablethreads in the thread pool. If there are no available threads inthe thread pool, the Executor creates a new thread or waits for athread to become available and assigns that thread theRunnable that was passed to method execute.
Depending on the Executor type, there may be a limit to thenumber of threads that can be created.
Interface ExecutorService(package java.util.concurrent) is a
subinterface of Executor that declares a number of othermethods for managing the life cycle of the Executor.
An object that implements the ExecutorService interface can becreated using static methods declared in class Executors
(package java.util.concurrent).
8/10/2019 M9 - Concurrency
34/40
Example
8/10/2019 M9 - Concurrency
35/40
Example (Cont)
8/10/2019 M9 - Concurrency
36/40
8/10/2019 M9 - Concurrency
37/40
Example (Cont
8/10/2019 M9 - Concurrency
38/40
8/10/2019 M9 - Concurrency
39/40
39
Questions and Comments
8/10/2019 M9 - Concurrency
40/40
Activity
1) Open your SEF workspace in
Eclipse.
2) In the package explorer, navigate to
the following package
sef.module10.activity.
3) The files TaskQueue and
QueueWorker attempt to simulate a
very common pattern when taking
advantage of Threads. Take the
time to review the implementation
and attempt to describe the pattern
and review its benefits.
Top Related