Advanced Object-Oriented Programming
Chapter 1 - Threads
UFAZ / 2018-2019
Cecilia ZANNI-MERK
Agenda
● Introducing Threads
● Synchronization
● Scheduling and Priority
● Thread Groups
2
Notion of process
A process is a running program. The system allocates a
portion of memory to each process (to store its
instructions, variables, etc.) and it associates information
to it (identifier, priorities, access rights, etc.).
A process runs on a system processor. It needs resources:
the processor, memory, inputs/outputs. Some resources have
only one access point and can therefore only be used by one
process at a time (for example, a printer).
3
Notion of process
Processes are then said to be mutually exclusive if they
share the same so-called critical resource. It is necessary
to have a synchronization policy for such a shared resource.
For example, regarding printing, there is a process that
manages the requests and the queue for these requests. Such
a process, that is invisible and always running as long as
the system is running, is called a daemon.
4
Notion of process
A daemon is a process that runs in the background like the
print service. Usually a daemon is started by the operating
system at boot time and stops at system shutdown.
A process can be in different states :
● running
● ready to run (but no free processor to run it)
● blocked (because of lack of resources)
5
Notion of process
1. Process blocks for
running
input
3
2. Scheduler picks
another process
2
1
3. Scheduler picks this
ready process
4. Input becomes
available
4 blocked
6
Threads
A thread or light process is a process within a process.
In Java, when we launch the virtual machine to execute a
program, we launch a process; this process is composed of
several threads: the main thread (which corresponds to the
main method) and other threads like the garbage collector.
So a process is composed of several threads (or tasks) and
will have to share its resources between its different
threads.
7
Threads
In Java there are two ways to create a thread:
● extending the Thread class: we will then have an object
that controls a task,
● implementing the Runnable interface: we will have an
object that represents the source code to execute.
8
Inheriting from the Thread class
When we inherit from the Thread class, we must rewrite the
void run() method so that it executes the expected behavior.
Then once a Thread object is created, this object can invoke
the void start() method of the Thread class which itself
invokes the rewritten run() method.
9
Example
10
Overview of the Thread class
Constants
● static int MAX_PRIORITY : maximum priority = 10
● static int MIN_PRIORITY : minimum priority = 1
● static int NORM_PRIORITY : normal priority = 5
Constructors
● Thread() ;
● Thread(Runnable target, String name)
● . . .
11
Overview of the Thread class
Methods
● void start() : invokes the run method
● void run() : executes the thread and can launch
InterruptedException
● int getPriority() : returns the priority level
● static Thread currentThread() : returns the thread that
is running
● static void sleep(long m) : suspends thread activity
running for m milliseconds
12
Overview of the Thread class
Methods
● static void yield() : suspends the activity of the
running thread and allows other threads to run
● void join() : waits for the end of the Thread object that
invokes it
● void interrupt() : interrupt this
● static boolean interrupted(): tests if the current thread
has been interrupted
13
Overview of the Thread class
Methods
● boolean isInterrupted() : test if this has been
interrupted
● boolean isAlive() : returns true if the thread has not
finished
● String toString() : returns the thread name, its
priority, its group in the ThreadGroup class
14
Example
15
Implementing the Runnable the interface
The Runnable interface contains only the run() method that
is to be implemented.
To launch a thread with a class implementing Runnable we use
the constructor of the Thread class which takes as parameter
a Runnable object.
16
Example
17
The join() method
The join() method of the Thread class invoked by a Thread
object t holds the thread running until t is finished.
The join() method launches an InterruptedException type
exception so it must be used in a try catch block.
18
Example
19
Threads management with synchronized
Threads can share resources. It must then be ensured that
this resource will only be used by one thread at a time.
To do this, a lock mechanism is used: any object (or array)
has a lock that can be opened or closed. A t1 thread can
close a lock on an object (if the lock is not already
closed) and when it finishes the execution of some code on
the locked object, it reopens the lock.
To prevent another t2 thread from executing some code on the
locked object, this code portion must have the same lock
20
mechanism on this object.
Threads management with synchronized
To prevent another t2 thread from executing some code on the
locked object, this code portion must have the same lock
mechanism on this object.
We can synchronize
● a method m: synchronized void m() - here this is the
object on which the lock is placed
● an object o: synchronized(o)...instructions ... - here o
is the object on which the lock is placed
21
Threads management with synchronized
While executing a portion of code marked synchronized by a
t1 thread, any other t2 thread attempting to execute a
portion of code marked synchronized relative to the same
object is suspended.
22
Threads management with synchronized
Remarks:
● attention! an unsynchronized method can modify this even
if this is locked by a synchronized method
● a static method can be synchronized, it then locks its
class preventing another static method from executing
during its own execution
● a synchronized static method does not prevent changes to
class instances by instance methods.
23
Example with no synchronization
24
Example with no synchronization
25
Example with no synchronization
26
Example with no synchronization
Execution
27
Example with synchronization
28
Example with synchronization
Execution
29
wait() and notify()
Another tool to coordinate actions of multiple threads in
Java is guarded blocks.
Such blocks keep a check for a particular condition before
resuming the execution.
With that in mind, we can use:
● Object.wait() – to suspend a thread
● Object.notify() – to wake a thread up
30
wait() and notify()
More in detail:
● public final void wait()
● public final void wait(long maxMilli)
● public final void wait(long maxMill, int maxNano)
● public final void notify()
● public final void notifyAll()
31
wait() and notify()
Simply put, a call to wait() forces the current thread to
wait until some other thread invokes notify() or notifyAll()
on the same object.
For this, the current thread must have executed:
● a synchronized instance method for the given object
● the body of a synchronized block on the given object
● synchronized static methods for objects of type Class
32
Example
In this example we have 4 classes:
● a Producer class that places objects in a warehouse
● a Consumer class that takes the objects from a warehouse
● a Warehouse class
● a Test class
33
Example
A Producer can put an object only if the warehouse is not
full; it must therefore wait until a Consumer has emptied
the warehouse,
A Consumer cannot take an item if the warehouse is empty; it
must therefore wait until a Producer has filled in the
warehouse.
34
First version: Warehouse takes care of synchronisation
35
First version: Warehouse takes care of synchronisation
36
First version: Warehouse takes care of synchronisation
37
2nd version: Producer and Consumer manage synch.
38
2nd version: Producer and Consumer manage synch.
39
2nd version: Producer and Consumer manage synch.
40
2nd version: Producer and Consumer manage synch.
41
Final remarks
42
Supervised exercises
1. Download and test all the examples presented during the lecture
a. Slide 19. Execute several times the example and compare the results
of those executions. What happens if you change the number of
milliseconds in the sleep method? Explain and justify
b. Do the same for the examples in slides 29 and 37
c. Compare the two versions of the same problem in slides 37 and 41.
Discuss the advantages and disadvantages of both approaches
2. Download and analyse the source code in slide 43 (classes
MyObject.java, MyThread.java, Deadlock.java)
a. Explain where there are mistakes and propose solutions.
b. Study the notions of starvation, livelock and deadlock and how to
prevent them
43
Supervised exercises
44
Mini-Project
To be developed by pairs of students and to be defended in 2 weeks
● Write a Counter class that inherits from the Thread class; it
has a String type attribute; its run() method counts from 1 to n
by making a random pause of 0 to 5 seconds between two
increments, it displays each incremented value with its name and
then displays an end message. Test this class in a TestCounter
class that starts several Counter objects.
● Modify the run() method of the Counter class so that the thread
displays the end message with its order of arrival. Test the
change.
45