CSCI213 Spring2013 Lectures Multithreading
CSCI213 Spring2013 Lectures Multithreading
Topic Goals
To understand how multiple threads can execute in parallel To learn how to implement threads To understand race conditions and deadlocks To be able to avoid corruption of shared objects by using locks and conditions
CSE UOWD
Process
Resources ownership
process includes a virtual address space to
Scheduling/execution
follows an execution path that may be
CSE UOWD
Threads
Individual execution unit within a process Each thread has a control block, with a state (Ready/Running/Blocked), saved registers, instruction pointer Separate stack
CSE UOWD
Benefits of Threads
Takes less time to create a new thread than a process Less time to terminate a thread than a process Less time to switch between two threads within the same process Since threads within the same process share memory and files, they can communicate with each other without invoking the kernel
CSE UOWD
Types
CSE UOWD
Examples
Foreground/Background
Backing up in background
set
Organization
For a word processing program, may allow
CSE UOWD
Threads Properties
Suspending a process involves suspending all threads of the process since all threads share the same address space Termination of a process, terminates all threads within the process
CSE UOWD
Java Threads
A thread is a program unit that is executed independently of other parts of the program The Java Virtual Machine executes each thread in the program for a short amount of time This gives the impression of parallel execution
CSE UOWD
10
Using a Thread
Develop a class that implements the Runnable interface
public interface Runnable { void run(); }
Place the code for your task into the run method of your class
public class MyRunnable implements Runnable { public void run() { // Task statements go here ... } }
CSE UOWD
11
CSE UOWD
12
Example
A program to print a time stamp and Hello World once a second for ten seconds:
Fri Fri Fri Fri Fri Fri Fri Fri Fri
CSE UOWD
12 12 12 12 12 12 12 12 12
13
GreetingRunnable
public class GreetingRunnable implements Runnable { public GreetingRunnable(String aGreeting) { greeting = aGreeting; } public void run() { // Task statements go here ... } // Fields used by the task statements private String greeting; }
CSE UOWD
14
CSE UOWD
15
GreetingRunnable
We can get the date and time by constructing a Date object
Date now = new Date();
16
CSE UOWD
17
GreetingRunnable.java
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
CSE UOWD
import java.util.Date; /** A runnable that repeatedly prints a greeting. */ public class GreetingRunnable implements Runnable { /** Constructs the runnable object. @param aGreeting: the greeting to display */ public GreetingRunnable(String aGreeting) { greeting = aGreeting; } public void run() { try { for (int i = 1; i <= REPETITIONS; i++) {
CSCI 213: Multithreading Spring 2013
18
GreetingRunnable.java (2)
23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: } Date now = new Date(); System.out.println(now + " " + greeting); Thread.sleep(DELAY); } } catch (InterruptedException exception) { } } private String greeting; static final int REPETITIONS = 10; static final int DELAY = 1000;
CSE UOWD
19
CSE UOWD
20
GreetingThreadRunner.java
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: /** This program runs two greeting threads in parallel. */ public class GreetingThreadRunner { public static void main(String[] args) { GreetingRunnable r1 = new GreetingRunnable("Hello, World!"); GreetingRunnable r2 = new GreetingRunnable("Goodbye, World!"); Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); } }
CSE UOWD
21
Output
Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri
CSE UOWD
Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr Apr
12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12
00:57:46 00:57:46 00:57:47 00:57:47 00:57:48 00:57:48 00:57:49 00:57:49 00:57:50 00:57:50 00:57:51 00:57:51 00:57:52 00:57:52 00:57:53 00:57:53 00:57:54 00:57:54 00:57:55 00:57:55
GST GST GST GST GST GST GST GST GST GST GST GST GST GST GST GST GST GST GST GST
2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
Hello, World! Goodbye, World! Hello, World! Goodbye, World! Goodbye, World! Hello, World! Hello, World! Goodbye, World! Hello, World! Goodbye, World! Hello, World! Goodbye, World! Goodbye, World! Hello, World! Hello, World! Goodbye, World! Goodbye, World! Hello, World! Hello, World! Goodbye, World!
22
Thread Scheduler
The thread scheduler runs each thread for a short amount of time (a time slice) Then the scheduler activates another thread There will always be slight variations in running times especially when calling operating system services (e.g. input and output) There is no guarantee about the order in which threads are executed
CSE UOWD
23
Terminating Threads
A thread terminates when its run method terminates Do not terminate a thread using the deprecated stop method Instead, notify a thread that it should terminate
t.interrupt();
structure
24
public void run() { for (int i = 1; i <= "REPETITIONS" && !Thread.interrupted(); i++) { // Do work } // Clean up }
CSE UOWD
25
CSE UOWD
public void run() { try { for (int i = 1; i <= REPETITIONS; i++) { // Do work } } catch (InterruptedException exception) { } // Clean up CSCI 213: Multithreading } Spring 2013
26
CSE UOWD
27
Race Conditions
When threads share a common object, they can conflict with each other Sample program: multiple threads manipulate a bank account Here is the run method of DepositRunnable: public void run() { try { for (int i = 1; i <= count; i++) { account.deposit(amount); Thread.sleep(DELAY);
CSE UOWD
28
CSE UOWD
29
Sample Application
Create a BankAccount object Create two sets of threads:
Each thread in the first set repeatedly deposits $100 Each thread in the second set repeatedly withdraws $100
CSE UOWD
30
10
31
The balance field is still 0, and the newBalance local variable is 100 2. The deposit thread reaches the end of its time slice and a withdraw thread gains control 3. The withdraw thread calls the withdraw method which withdraws $100 from the balance variable; it is now -100 4. The withdraw thread goes to sleep
CSE UOWD
32
The balance is now 100 instead of 0 because the deposit method used the OLD newBalance
CSE UOWD
33
11
CSE UOWD
34
Race Condition
Occurs if the effect of multiple threads on shared data depends on the order in which they are scheduled It is possible for a thread to reach the end of its time slice in the middle of a statement It may evaluate the right-hand side of an equation but not be able to store the result until its next turn
public void deposit(double amount) { balance = balance + amount; System.out.print("Depositing " + amount + ", new balance is " + balance); }
35
class
CSE UOWD
36
12
CSE UOWD
37
CSE UOWD
38
39
13
CSE UOWD
40
41
Avoiding Deadlocks
A deadlock occurs if no thread can proceed because each thread is waiting for another to do some work first BankAccount example
public void withdraw(double amount) { balanceChangeLock.lock(); try { while (balance < amount) Wait for the balance to grow ... } finally { balanceChangeLock.unlock(); } }
CSE UOWD
42
14
(balance)
Other threads will call deposit, but will be blocked until withdraw exits But withdraw doesnt exit until it has funds available DEADLOCK
CSE UOWD
43
Condition Objects
To overcome problem, use a condition object Condition objects allow a thread to temporarily release a lock, and to regain the lock at a later time Each condition object belongs to a specific lock object
CSE UOWD
44
CSE UOWD
45
15
CSE UOWD
46
47
To unblock, another thread must execute signalAll on the same condition object
sufficientFundsCondition.signalAll();
signalAll unblocks all threads waiting on the condition signal: randomly picks just one thread waiting on the object and unblocks it signal can be more efficient, but you need to know that every waiting thread can proceed Recommendation: always call signalAll
CSE UOWD
48
16