internet software development controlling threads paul j krause
TRANSCRIPT
Internet Software Internet Software DevelopmentDevelopment
Controlling ThreadsControlling Threads
Paul J KrausePaul J Krause
ContentsContents
Quick recapQuick recap Thread SafetyThread Safety SynchronizationSynchronization LocksLocks Guarded suspensionGuarded suspension
Threads vs. ProcessesThreads vs. Processes
A thread is a single flow of control A thread is a single flow of control withinwithin a a programprogram
It performs one of the tasks that a program It performs one of the tasks that a program needs to perform to achieve its goalsneeds to perform to achieve its goals
If a program needs to perform several tasks, If a program needs to perform several tasks, these could be handled in different threads (and these could be handled in different threads (and hence performed hence performed concurrentlyconcurrently))
These threads will interact and cooperate These threads will interact and cooperate through a through a sharedshared memory space memory space
The Risks of ThreadsThe Risks of Threads
Different threads can interact via shared Different threads can interact via shared variables and objectsvariables and objects
The execution of each thread may The execution of each thread may proceed independently of the othersproceed independently of the others
In general, the relative ordering of In general, the relative ordering of execution of the different threads is non-execution of the different threads is non-deterministicdeterministic
This can lead to This can lead to safetysafety and and livenessliveness problemsproblems
Thread SafetyThread Safety
Properties that we require to hold Properties that we require to hold throughout the lifetime of a programthroughout the lifetime of a program
Essentially saying “Nothing bad should Essentially saying “Nothing bad should happen”happen”
Bad Things typically Bad Things typically cancan happen if a happen if a thread is interrupted whilst in the process thread is interrupted whilst in the process of modifying an objectof modifying an object
Bank Account ClassBank Account Class
public class Account {public class Account {private long balance;private long balance;// …// …public boolean withdraw(long amount) {public boolean withdraw(long amount) {
if (amount <= balance) {if (amount <= balance) {balance = balance - amount;balance = balance - amount;return true;return true;}}
else { return false; }else { return false; }}}
}}
This could happen!This could happen!
BalanceBalance Withdraw1Withdraw1 Withdraw2Withdraw2
1,000,0001,000,000 amount <= balanceamount <= balance
1,000,0001,000,000 amount <= balanceamount <= balance
00 balance = …;balance = …;
-1,000,000-1,000,000 balance = …;balance = …;
-1,000,000-1,000,000 return true;return true;
-1,000,000-1,000,000 return true;return true;
SynchronisationSynchronisation
This was an example of a This was an example of a race conditionrace condition To be thread-safe, a class must ensure:To be thread-safe, a class must ensure:
consistency of the states of its instances, andconsistency of the states of its instances, and consistency of the results of method invocations in the consistency of the results of method invocations in the
presence of multiple threadspresence of multiple threads
We have seen the Account class is not thread-We have seen the Account class is not thread-safesafe
We can use We can use SynchronisationSynchronisation to make it thread- to make it thread-safesafe
Synchronisation IISynchronisation II
What was the problem with the Account class?What was the problem with the Account class? Answer -Answer - More than one thread at a time was able to enter More than one thread at a time was able to enter
a “critical region” in the codea “critical region” in the code We need to:We need to:
identify sections of code that should only be accessed identify sections of code that should only be accessed by one thread at a timeby one thread at a time
use the Java synchronisation mechanism to ensure a use the Java synchronisation mechanism to ensure a second thread cannot access a critical sectionsecond thread cannot access a critical section
Making operations atomicMaking operations atomic
An An atomic operationatomic operation is one that cannot be is one that cannot be interruptedinterrupted
Reading and assignment of variables of Reading and assignment of variables of primitive types is atomicprimitive types is atomic except except longlong and and doubledouble
For other operations, use For other operations, use synchronizedsynchronized to make them atomicto make them atomic
Synchronising methodsSynchronising methods
class MyClass {class MyClass {
synchronized void aMethod() {synchronized void aMethod() {
// do some stuff …// do some stuff …
}}
}}
Here, the whole method is in the critical Here, the whole method is in the critical regionregion
Synchronising statementsSynchronising statements
class MyClass {class MyClass {
void aMethod() {void aMethod() {
// do some stuff …// do some stuff …
synchronised(this) {synchronised(this) {
// atomic stuff …// atomic stuff …
}}
}}
}}
““this” could be replaced by some other this” could be replaced by some other reference typereference type
What to synchronize?What to synchronize?
public class Account {public class Account {private long balance;private long balance;// …// …public boolean withdraw(long amount) {public boolean withdraw(long amount) {
if (amount <= balance) {if (amount <= balance) {balance = balance - amount;balance = balance - amount;return true;return true;}}
else { return false; }else { return false; }}}
}}
LocksLocks
Each object has an associated Each object has an associated locklock A thread must obtain exclusive possession A thread must obtain exclusive possession
of the appropriate lock before it can enter of the appropriate lock before it can enter a critical regiona critical region i.e. the region marked by a i.e. the region marked by a synchronizedsynchronized
statementstatement The lock is released when the thread The lock is released when the thread
leaves the critical regionleaves the critical region
Which lock?Which lock?
For a synchronized instance method, the For a synchronized instance method, the lock belongs to “lock belongs to “thisthis” instance” instance
For a synchronized statement:For a synchronized statement:synchronised(exp) {synchronised(exp) {
// atomic stuff …// atomic stuff …
}} the lock associated with the lock associated with expexp is used is used
Sharing locksSharing locks
public class A {public class A {
synchronized void m1() { … }synchronized void m1() { … }
synchronized void m2() { … }synchronized void m2() { … }
void m3() { … }void m3() { … }
}}
Is that sufficient?Is that sufficient?
Thread
Producer Consumer
SyncBoundedQueue
Cooperating threadsCooperating threads
Can resolve additional problems with the Can resolve additional problems with the use of use of guarded suspensionguarded suspension
The guard is tested before a method is The guard is tested before a method is executedexecuted
If the guard is true, execution of the If the guard is true, execution of the method will continuemethod will continue
If the guard is false, execution will be If the guard is false, execution will be suspended until it becomes truesuspended until it becomes true
Thread controlThread control
Guarded suspension can be implemented Guarded suspension can be implemented through the use of the following thread control through the use of the following thread control methods:methods:
wait():wait(): This is invoked if a thread is This is invoked if a thread is temporarily unable to continue (the guard is temporarily unable to continue (the guard is false)false)
notify():notify(): One thread notifies another thread One thread notifies another thread that it may continuethat it may continue
notifyAll():notifyAll(): All threads in the wait queue All threads in the wait queue associated with the receiving object will be associated with the receiving object will be notifiednotified
SummarySummary
Multiple threads may lead to safety issuesMultiple threads may lead to safety issues We have seen how synchronisation can We have seen how synchronisation can
be used to make programs “thread-safe”be used to make programs “thread-safe” But that still does not mean that multi-But that still does not mean that multi-
threaded programs will be perfectly threaded programs will be perfectly behavedbehaved
We have introduced guarded suspension We have introduced guarded suspension to solve additional problemsto solve additional problems