1 / 13

Locks (Java 1.5)

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

Download Presentation

Locks (Java 1.5)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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. // A bank account has a balance that can be changed by // deposits and withdrawals. publicclass BankAccount { public BankAccount() { balance = 0; } publicvoid deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } publicvoid withdraw(double amount) { System.out.print("Withdrawing " + amount); double newBalance = balance - amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } publicdouble getBalance() { return balance; } privatedouble balance; } An example with bank accounts

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

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

  6. /** This program runs four threads that deposit and withdraw money from the same bank account. */ publicclass BankAccountThreadTester { publicstaticvoid main(String[] args) { BankAccount account = new BankAccount(); finaldouble AMOUNT = 100; finalint 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. 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 ( ) • publicclass 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

  8. 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: • publicvoid 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?

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

  10. 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

  11. 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. publicclass BankAccount { public BankAccount() { balance = 0; balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); } publicvoid 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(); } } The BankAccount class with locks and conditions

  12. publicvoid 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(); } } publicdouble getBalance() { return balance; } privatedouble balance; private Lock balanceChangeLock; private Condition sufficientFundsCondition; }

More Related