Presentation is loading. Please wait.

Presentation is loading. Please wait.

Locks (Java 1.5) Only one thread can hold a lock at once –Other threads that try to acquire it block (or become suspended) until lock becomes available.

Similar presentations


Presentation on theme: "Locks (Java 1.5) Only one thread can hold a lock at once –Other threads that try to acquire it block (or become suspended) until lock becomes available."— Presentation transcript:

1 Locks (Java 1.5) Only one thread can hold a lock at once –Other threads that try to acquire it block (or become suspended) until lock becomes available Reentrant lock can be reacquired by same thread –As many times as desired –No other thread may acquire lock until has been released same number of times has been acquired interface Lock { Void lock(); Void unlock(); …//some other stuff }

2 Synchronization Using Locks public class Example extends Thread { private static int cnt = 0; private Lock lock; public Example(){ lock = new ReentrantLock(); } public void run() { lock.lock(); int y = cnt; cnt = y + 1; lock.unlock(); }... } Creating a lock, for protecting the shared state Acquires the lock; Only succeeds if not held by another thread Releases the lock

3 An example with bank accounts // A bank account has a balance that can be changed by // deposits and withdrawals. public class BankAccount { public BankAccount() { balance = 0; } public void deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } public void withdraw(double amount) { System.out.print("Withdrawing " + amount); double newBalance = balance - amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } public double getBalance() { return balance; } private double balance; }

4 /** A deposit runnable makes periodic deposits to a bank account. */ public class DepositRunnable implements Runnable { public DepositRunnable(BankAccount anAccount, double anAmount, int aCount) { account = anAccount; amount = anAmount; count = aCount; } public void run() { try { for (int i = 1; i <= count; i++) { account.deposit(amount); Thread.sleep(DELAY); } catch (InterruptedException exception) {} } private static final int DELAY = 1; private BankAccount account; private double amount; private int count; }

5 /** A withdraw runnable makes periodic withdrawals from a bank account. */ public class WithdrawRunnable implements Runnable { public WithdrawRunnable(BankAccount anAccount, double anAmount, int aCount) { account = anAccount; amount = anAmount; count = aCount; } public void run() { try { for (int i = 1; i <= count; i++) { account.withdraw(amount); Thread.sleep(DELAY); } catch (InterruptedException exception) {} } private static final int DELAY = 1; private BankAccount account; private double amount; private int count; }

6 /** This program runs four threads that deposit and withdraw money from the same bank account. */ public class BankAccountThreadTester { public static void main(String[] args) { BankAccount account = new BankAccount(); final double AMOUNT = 100; final int REPETITIONS = 5; DepositRunnable d1 = new DepositRunnable( account, AMOUNT, REPETITIONS); WithdrawRunnable w1 = new WithdrawRunnable( account, AMOUNT, REPETITIONS); DepositRunnable d2 = new DepositRunnable( account, AMOUNT, REPETITIONS); WithdrawRunnable w2 = new WithdrawRunnable(account, AMOUNT, REPETITIONS); Thread t1 = new Thread(d1); Thread t2 = new Thread(w1); Thread t3 = new Thread(d2); Thread t4 = new Thread(w2); t1.start(); t2.start(); t3.start(); t4.start(); }

7

8 Using Locks to Synchronize Threads Step 1: add a lock to the class that owns the shared resource Step 2: surround any code that uses the shared resource by a call to lock ( ) and unlock ( ) public class BankAccount { public BankAccount() { balanceChangeLock = new ReentrantLock(); // the rest of your code here } … // more code here private Lock balanceChangeLock; } balanceChageLock.lock ( ); try { // Code that changes the balance } finally { balanceChangeLock.unlock ( ); } Use finally block to ensure that the lock is released even if exception happens

9 Deadlocks Deadlock occurs when a thread acquires a lock and then must wait for another thread to do some work before proceeding, but where the second thread needs the lock to proceed Example: Let’s assume we want to prevent a withdrawal if there is not enough balance –In a single threaded world, we might code: if (account.getBalance ( ) >= amount) account.withdraw (amount); –For multi-threading: public void withdraw(double amount){ balanceChangeLock.lock(); try { while (balance < amount) // Wait until the balance becomes //sufficient (i.e., until a deposit is made) } finally{ balanceChangeLock.unlock(); } Call sleep() to wait?

10 Waiting and Signaling Using a Condition A thread waits on a condition (e.g., balance > 0 ) and another thread signals when the condition becomes true To create a condition –Condition c = balanceChangeLock.newCondition(); To start waiting on a condition –c.await(); To signal that a condition has become true –c.signalAll() or c.signal();

11 Waiting and Signaling Using a Condition Waiting threads are blocked and will not be considered for execution until the condition is signaled The lock must still be released before they can run Recall: Can also be done with an object’s built-in lock and condition: wait() to wait and notifyAll() or notify() to signal

12 The BankAccount class with locks and conditions import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; // A bank account has a balance that can be changed by // deposits and withdrawals. public class BankAccount { public BankAccount() { balance = 0; balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); } 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; sufficientFundsCondition.signalAll(); } finally { balanceChangeLock.unlock(); }

13 public void withdraw(double amount) throws InterruptedException { balanceChangeLock.lock(); try { while (balance < amount) sufficientFundsCondition.await(); System.out.print("Withdrawing " + amount); double newBalance = balance - amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } finally { balanceChangeLock.unlock(); } public double getBalance() { return balance; } private double balance; private Lock balanceChangeLock; private Condition sufficientFundsCondition; }


Download ppt "Locks (Java 1.5) Only one thread can hold a lock at once –Other threads that try to acquire it block (or become suspended) until lock becomes available."

Similar presentations


Ads by Google