CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009...

24
CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread- Safety December 1, 2009 Nick Leidenfrost

Transcript of CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009...

Page 1: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

CSE 501NFall ‘0923: Advanced Multithreading: Synchronization and Thread-Safety

December 1, 2009

Nick Leidenfrost

Page 2: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

2

Lecture Outline

The Last Lecture! No new information after this No more listening to me talk!* *Does not include semester review *…Or me showing up at your house randomly and start talking about

Java *Seriously, what’s your address?

Continue with multi-threadingQuick RecapHow to prevent race conditions

Page 3: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

3

Recap Threads

Create a parallel chain of execution Can create a thread by subclassing java.lang.Thread and

overriding the run method Call start on your class

Runnable objects Have your class implement java.lang.Runnable Define the run method, pass Runnable into a new Thread Call start on the Thread

Race conditions When two Threads want to use a resource at the same time, the

state of the resource may be compromised Note, the resource must be an instance variable, as each

Thread gets its own copy of local variables

Page 4: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

4

The synchronized keyword Can declare methods to be synchronized

When a method is synchronized: The method itself executes atomically

Only one thread can be in any synchronized method on an object at once

All other method calls on the object are held Have to be careful about synchronization

Quick and easy way to prevent race conditions, but… Can more easily cause deadlocks

public synchronized void deposit (double amount) {

// ...

}

Page 5: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

5

The synchronized keyword

We can also declare synchronized blocks

Synchronized blocks have to be given an object to synchronize on

public void deposit (double amount) {

synchronized (this) {

// ... Critical section

}

}

Page 6: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

6

synchronizedThe Downside

Because the synchronized block is a syntactical construct, it is relatively inflexibleCritical sections must be contained within a

block statementAn application may need more selective

control over locking and unlocking resources In the control-flow of a downstream method Conditional locking / unlocking

Page 7: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

7

Deadlocks

A deadlock occurs if no thread can proceed because each thread is waiting for another to do some work first

Your program may stall completely, or some element of functionality (controled by the deadlocked thread) may become unresponsive

Page 8: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

8

LocksMore flexible methods of Mutual Exclusion

Aside from the synchronized keyword, we can also provide mutually exclusive access to a critical section with lock objects

Several types of these objects are available in the package java.util.concurrent.locks

We will focus on the ReentrantLock Allows a Thread to reacquire a lock that it already

owns

Other types of locks: ReadWriteLock

Page 9: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

9

Synchronizing Resource Access

Typically, a lock object is added to a class whose methods access shared resources, like this:public class BankAccount {

private double balance;

private Lock balanceChangeLock;

public BankAccount() {

balanceChangeLock = new ReentrantLock(); . . . } . . . }

Page 10: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

10

Synchronizing Resource Access

Code that manipulates shared resource is surrounded by calls to lock and unlock:

public void deposit (double amount) {balanceChangeLock.lock(); // Code that manipulates the shared resource

balanceChangeLock.unlock();}

Page 11: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

11

Synchronizing Resource Access When a thread calls lock, it “owns” the lock

until the thread calls unlock Any thread that calls lock while another thread

owns the lock is temporarily deactivatedThe lock method blocks if the lock is already

owned by another thread Thread scheduler periodically reactivates

thread so it can try to acquire the lock Eventually, waiting thread can acquire the lock

Page 12: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

12

Synchronizing Resource Access Because calling lock causes other threads

to block until they acquire the lock, it is very important to make sure the lock is properly released

If code between calls to lock and unlock throws an exception, call to unlock never happens

To overcome this problem, place call to unlock into a finally clause:

Page 13: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

13

Synchronizing Resource Access with Locks

public void deposit(double amount) {

balanceChangeLock.lock(); try { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } finally { balanceChangeLock.unlock(); } }

Page 14: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

14

Visualizing Object Locks

Page 15: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

15

Avoiding Deadlocks

public void withdraw(double amount) { balanceChangeLock.lock(); try { while (balance < amount) Wait for the balance to grow . . . } finally { balanceChangeLock.unlock(); }}

• BankAccount example

Page 16: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

16

Avoiding Deadlocks How can we wait for the balance to grow? We can't simply call sleep inside withdraw method; thread will block all other threads that want to use balanceChangeLock

In particular, no other thread can successfully execute deposit

Page 17: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

17

Avoiding Deadlocks Other threads will call deposit, but will be

blocked until withdraw exits But withdraw doesn't exit until it has

funds available DEADLOCK

Page 18: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

18

Condition Objects To overcome problem, use a Condition

object (also contained in package java.util.concurrent.locks)

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

Page 19: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

19

Condition Objects You obtain a condition object with newCondition method of Lock interface

public class BankAccount { private Lock balanceChangeLock; private Condition sufficientFundsCondition;

public BankAccount() { balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); . . . } . . . }

Page 20: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

20

Condition Objects It is customary to give the condition object

a name that describes condition to test You need to implement an appropriate test

to see if lock can be released As long as test is not fulfilled, call await on

the condition object:

Page 21: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

21

Condition Objects

public void withdraw(double amount) {

balanceChangeLock.lock(); try { while (balance < amount) sufficientFundsCondition.await(); . . . } finally { balanceChangeLock.unlock(); } }

Page 22: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

22

Condition Objects Calling await

Makes current thread wait Allows another thread to acquire the lock object

To unblock, another thread must execute signalAll on the same condition object

signalAll unblocks all threads waiting on the condition

sufficientFundsCondition.signalAll();

Page 23: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

23

Condition Objects 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

Page 24: CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.

24

Conclusion

Lab 8 Part 3 Assigned – Due by Midnight on the 15th

Quiz 6 Now In Lab Afterwards