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

Preview:

Citation preview

CSE 501NFall ‘0923: 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

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

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) {

// ...

}

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

}

}

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

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

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

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(); . . . } . . . }

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();}

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

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:

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(); } }

14

Visualizing Object Locks

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

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

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

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

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(); . . . } . . . }

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:

21

Condition Objects

public void withdraw(double amount) {

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

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();

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

24

Conclusion

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

Quiz 6 Now In Lab Afterwards

Recommended