Threads in Java
Alexandre Bergel
[Link]
06/11/2017
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] executions
[Link]
[Link]
[Link] words
[Link]
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] executions
[Link]
[Link]
[Link] words
[Link]
More than one thing
Most of the programs we have seen use a single
thread for their execution
This may cause problem when multiple events or
actions need to occur at the same time
Drawing a graphical tictactoe while handling user’s clicks
Serving a HTTP request while waiting for new request
Example of a web server
[Link]
request
[Link]
Example of a web server
[Link]
request
[Link]
1 - receive the request
2 - interpret the request
3 - look for the html file to
serve
4 - send the file over
Example of a web server
[Link]
request
[Link]
costly operation 1 - receive the request
(a few milliseconds) 2 - interpret the request
3 - look for the html file to
serve
4 - send the file over
Example of a web server
[Link]
request
[Link]
costly operation 1 - receive the request
(a few milliseconds) 2 - interpret the request
3 - look for the html file to
If the server receives many
requests per seconds, then the serve
server should be able to do 4 - send the file over
many things at the same time
Threads
The solution to these problems is the seamless
execution of two or more sections of a program, at the
same time
Threads: expressing logical parallelism in a program
thread = logical sequence of control, a program’s path of
execution
independent logical sequences of control
generally share one memory
Threads give the illusion to do some work in parallel
What are threads?
Threads are a control mechanism offered by both a
library and the programming language
Used to express concurrency and parallelism in a
program
The following operations are necessary:
create: increase parallelism
synchronize: coordinate
destroy: decrease parallelism
Multiple execution
Multithreading means multiple execution lines for a
single program at the same time
The idea of sharing data is very beneficial
but brings up some areas of concern
What are threads in Java?
Threads are exposed as a special kind of object
Operations are methods on thread objects
Each thread object is a unit of parallelism
A thread can be executed independently therefore
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] executions
[Link]
[Link]
[Link] words
[Link]
Jeronimo v0 - Testing first
public class JeronimoTest {
@Test
public void test() {
LoggingHandler handler = new LoggingHandler();
Jeronimo server = new Jeronimo(handler);
assertEquals([Link](), 0);
[Link]("[Link]
assertEquals([Link](), 1);
assertEquals([Link](), "[Link]
}
}
The Jeronimo class
public class Jeronimo {
private RequestHandler requestHandler;
public Jeronimo(RequestHandler aRequestHandler) {
requestHandler = aRequestHandler;
}
public void receiveRequest(String aRequest) {
[Link](aRequest);
}
}
public interface RequestHandler {
void serve(String aRequest);
}
Writing the right handler
public class ThreadedHandler implements RequestHandler, Runnable {
@Override
public void serve(String aRequest) {
Thread thread = new Thread(this);
[Link]();
}
@Override
public void run() {
...
}
...
}
Testing the creation of threads is not trivial
in most of case
Handing web requests
Web
server
Thread 1
Handing web requests
Web
server
Thread 1
[Link]
Handing web requests
Web
server creates
Thread 1
[Link]
Request
Thread 2
Handing web requests
Web
server
Thread 1
[Link]
Request
Thread 2
Handing web requests
[Link]
Web
server
Thread 1
[Link]
Request
Thread 2
Jeronimo v1 - Adding a bit of
networking
A request has to be associated to a socket
A socket is an endpoint for communication between
two machine
Using sockets
public class JeronimoTest {
@Test
public void test() {
LoggingHandler handler = new LoggingHandler();
Jeronimo server = new Jeronimo(handler);
assertEquals([Link](), 0);
[Link](new Socket());
assertEquals([Link](), 1);
}
...
}
public class Jeronimo {
private RequestHandler requestHandler;
private boolean running;
private final int port = 8000;
private ServerSocket serverSocket;
public Jeronimo() {
this(new ThreadedHandler());
}
public Jeronimo(RequestHandler aRequestHandler) {
requestHandler = aRequestHandler;
}
...
public class Jeronimo {
private RequestHandler requestHandler;
private boolean running;
private final int port = 8000; In network, a
private ServerSocket serverSocket; port is a
public Jeronimo() {
particular
this(new ThreadedHandler()); channel number
}
public Jeronimo(RequestHandler aRequestHandler) {
requestHandler = aRequestHandler;
}
...
...
public void start() {
running = true;
[Link]();
}
public void stop() {
running = false;
}
private void servingLoop() {
[Link]();
while (running) {
try {
// accept is a blocking operation
// it waits for a connection by a client
Socket socket = [Link]();
[Link](socket);
}
catch (IOException e) {
[Link](e);
}
}
} ...
...
public void receiveRequest(Socket socket) {
[Link](socket);
}
private void initServingSocket() {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
[Link]("Cannot create the socket.
Maybe the port is already in use?");
[Link](1);
}
}
public static void main(String[] argv) {
Jeronimo server = new Jeronimo();
[Link]();
}
}
Sending info to the client
public class ThreadedHandler implements RequestHandler,
Runnable {
...
@Override
public void run() {
increaseNumberOfReceivedRequests();
if ([Link]()) {
[Link]("<html>Hello World! Now is <i>"+
new Date().toString() +"</i></html>");
}
}
private void send(String textToSend) {
BufferedOutputStream out;
try {
out = new
BufferedOutputStream([Link]());
sendHeader(out, [Link]());
[Link]([Link]());
[Link]();
[Link]();
} catch (IOException e) {
[Link]();
[Link]("Error when writing");
}
}
// sendHeader write an http header HTTP 1.0 that is
understandable by the web browser
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] executions
[Link]
[Link]
[Link] words
[Link]
Two ways to create a thread
Java’s creators have designed two ways of creating
threads
Implementing the interface Runnable, or
Extending the class Thread
The Thread class
defined as a class in the core Java language
implements an interface called Runnable
define a single abstract method called run()
public interface Runnable {
public void run();
}
public class Thread implements Runnable { ... }
[Link]
There are a number of methods defined on the
Thread class
To query the thread to find its priority
To put it to sleep (note that sleep() is a static method)
Cause it to yield to another thread
stop, suspend, resume its execution
...
Implementing Runnable
public class ThreadedHandler implements RequestHandler, Runnable {
@Override
public void serve(Socket aSocket) {
socket = aSocket;
Thread thread = new Thread(this);
[Link]();
}
@Override
public void run() {
...
}
}
Creating a Thread
Steps
Create an object of type Runnable & bind it to a new Thread object
Or create an instance of a subclass of Thread
Start it
The [Link]() method
creates the thread stack for the thread
then invokes the run() method of the Runnable object in the new
thread
Threads operations
construction
usually done by passing a runnable object to the thread on
construction
starting
Invoking a thread’s start() method cases the run() method of the
runnable object to run
priority
Threads can be run at different priority levels
Thread life cycle
just created
New
stop()
start()
Terminated
under execution death
Runnable
Waiting
waiting for
another thread waiting for
Timed_
waiting a monitor
Blocked
waiting for
another thread
up to a given time
[Link]
[Link]
Issues with threads
Sharing and Synchronization
Threads may share access to objects (object state, open files, and
other resources) associated with a single process
Scheduling
if # of threads != # of cores (in the CPU), scheduling of threads is
an issue
Operations in different threads may occur in variety of orders
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] executions
[Link]
[Link]
[Link] words
[Link]
Example: a simple counter
public class SmallExample implements Runnable {
private String info;
public SmallExample(String info) { [Link] = info; }
public void run () {
for(int i = 1; i < 10; i++) {
[Link](info + " " + i);
}
}
public static void main(String[] argv) {
new Thread(new SmallExample("thread1")).start();
new Thread(new SmallExample("thread2")).start();
new Thread(new SmallExample("thread3")).start();
}
}
Example
thread1 1
thread1 2
thread1
thread1
3
4 Buh?
thread1 5
thread1
thread1
6
7
No parallelism?
thread1
thread1
8
9 What happened?
thread2 1
thread2 2
thread2 3
thread2 4
thread2 5
thread2 6
thread3 1
thread3 2
thread3 3
thread3 4
thread3 5
thread3 6
thread3 7
thread3 8
thread3 9
thread2 7
thread2 8
thread2 9
Example
thread1 1
thread1 2
thread1
thread1
3
4 Buh?
thread1 5
thread1
thread1
6
7
No parallelism?
thread1
thread1
8
9 What happened?
thread2 1
thread2 2
thread2 3
thread2 4
thread2 5
thread2 6
thread3
thread3
1
2
Each thread did not
thread3
thread3
3
4 wait for the others
thread3 5
thread3 6
thread3 7
thread3 8
thread3 9
thread2 7
thread2 8
thread2 9
Letting other thead execute
public class SmallExample implements Runnable {
private String info;
public SmallExample(String info) { [Link] = info; }
public void run () {
for(int i = 1; i < 10; i++) {
[Link](info + " " + i);
[Link](); //<= new instruction
}
}
public static void main(String[] argv) {
new Thread(new SmallExample("thread1")).start();
new Thread(new SmallExample("thread2")).start();
new Thread(new SmallExample("thread3")).start();
}
}
Letting other thead execute
public class SmallExample implements Runnable {
private String info; Causes the
currently
public SmallExample(String info) { [Link] = info; }
public void run () { executing thread
for(int i = 1; i < 10; i++) { object to
[Link](info + " " + i);
temporarily
[Link](); //<= new instruction
} pause and allow
}
other threads to
public static void main(String[] argv) { execute.
new Thread(new SmallExample("thread1")).start();
new Thread(new SmallExample("thread2")).start();
new Thread(new SmallExample("thread3")).start();
}
}
Slow down!
public class SmallExample implements Runnable {
private String info;
public SmallExample(String info) { [Link] = info; }
public void run () {
for(int i = 1; i < 10; i++) {
[Link](info + " " + i);
try {
[Link](1000);
} catch (InterruptedException e) {
[Link]();
}
}
}
...
Slow down!
public class SmallExample implements Runnable {
private String info;
Causes the currently
public SmallExample(String info) { [Link] = info; }
executing thread to
public void run () {
for(int i = 1; i < 10; i++) {
sleep (temporarily
cease
[Link](info + " " + i); execution) for
try {
[Link](1000);
the specified number
ofe)milliseconds
} catch (InterruptedException {
[Link]();
}
}
}
...
Making a thread live
public class Counter implements Runnable {
private int value = 0;
public void run () {
while (true) {
[Link](value);
value ++;
waitSecond(1);
}
}
private void waitSecond(int i) { ... }
public static void main(String[] argv) {
Counter counter = new Counter();
Thread thread = new Thread(counter);
[Link]();
[Link](3);
[Link]();
} }
Making a thread live
public class Counter implements Runnable {
private int value = 0;
public void run () {
while (true) {
[Link](value);
value ++;
waitSecond(1);
}
}
private void waitSecond(int i) { ... }
public static void main(String[] argv) {
Counter counter = new Counter();
Deprecated
Thread thread = new Thread(counter);
[Link](); method!
[Link](3);
[Link]();
} }
Making a thread live
public class Counter implements Runnable {
private int value = 0;
public void run () {
while (true) {
[Link](value);
value ++;
waitSecond(1);
}
}
private void waitSecond(int i) { ... }
public static void main(String[] argv) {
Counter counter = new Counter(); “This method is
inherently
Thread thread = new Thread(counter);
[Link]();
[Link](3); unsafe.”
[Link]();
} }
How to make a counter stop then?
public class Counter implements Runnable {
private int value = 0;
public void run () {
while (true) {
[Link](value);
value ++;
waitSecond(1);
}
}
private void waitSecond(int i) { ... }
public static void main(String[] argv) {
Counter counter = new Counter(); “This method is
inherently
Thread thread = new Thread(counter);
[Link]();
[Link](3); unsafe.”
[Link]();
} }
How to make a counter stop then?
public class Counter implements Runnable {
private int value = 0;
private boolean shouldRun = true;
public void run () {
while (shouldRun) { Introduce a
[Link](value);
value ++; running state
waitSecond(1);
}
}
public void stop() { shouldRun = false; }
private void waitSecond(int i) { ... }
public static void main(String[] argv) {
Counter counter = new Counter();
Thread thread = new Thread(counter);
[Link]();
[Link](3);
[Link]();
}
}
Thread priority
Each thread runs at a given priority
The runtime chooses the runnable thread with the
highest priority for execution
A thread gets the Runnable state according to their
priority
When a Java thread is created, it inherits its priority
from the thread that created it
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] executions
[Link]
[Link]
[Link] words
[Link]
Synchronization
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
Synchronization
If counter is an instance of SynchronizedCounter,
then having increment and decrement synchronized
has two effects:
First, it is not possible for two invocations of synchronized
methods on the same object to interleave. When one thread is
executing a synchronized method for an object, all other threads
that invoke synchronized methods for the same object block
(suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically
establishes a happens-before relationship with any subsequent
invocation of a synchronized method for the same object. This
guarantees that changes to the state of the object are visible to all
threads.
Note that constructors cannot be synchronized
Synchronization
If counter is an instance of SynchronizedCounter,
then having increment and decrement synchronized
has two effects:
First, it is not possible for two invocations of synchronized
methods on the same object to interleave. When one thread is
[Link]
executing a synchronized method for an object, all other threads
that invoketutorial/essential/concurrency/
synchronized methods for the same object block
(suspend execution) until the first thread is done with the object.
[Link]
Second, when a synchronized method exits, it automatically
establishes a happens-before relationship with any subsequent
invocation of a synchronized method for the same object. This
guarantees that changes to the state of the object are visible to all
threads.
Note that constructors cannot be synchronized
Joining threads
It is often the case that one need to wait for all the
threads.
for (Thread thread : threads) {
[Link]();
}
// We exit the for loop only if all the
threads are completed
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] execution
[Link]
[Link]
[Link] words
[Link]
Conclusion
Java threads are the basis for expressing of
parallelism
necessary to use more than one core
convenient, nice encapsulation, cleanly integrated
can build flexible expression and management
Do not overuse Threads
It may leads to complex and hard-to-debug situations
What you should know
What are threads?
Why threads are often necessary?
How to define a thread?
When you need to employ threads?
Understand what are the synchronization problems in
threading
What is a scheduler?
How to implement thread states and their transitions?
Can you answer to these questions?
Why each web request must be handled in a
separate thread?
Can you provide an example of synchronization
problem?
Why [Link]() is deprecated?
Roadmap
[Link] are threads?
[Link] Jeronimo Web Server
[Link] execution
[Link]
[Link]
[Link] words
[Link]
For Monday 13 November 2017
1 - Extent Jeronimo to indicate the number of served
requests
2 - Indicate the number of bytes sent over the
network