Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Race Conditions When threads share access to a common object/data, they can conflict with each other and mess up the consistency of the object/data.

Similar presentations


Presentation on theme: "1 Race Conditions When threads share access to a common object/data, they can conflict with each other and mess up the consistency of the object/data."— Presentation transcript:

1 1 Race Conditions When threads share access to a common object/data, they can conflict with each other and mess up the consistency of the object/data. ThreadUnsafeBankDeposit –Desirable output Current balance (d): 0.0, Depositing 100.0, New balance (d): 100.0 Current balance (w): 100.0, Withdrawing 100.0, New balance (w): 0.0 Current balance (d): 0.0, Depositing 100.0, New balance (d): 100.0 Current balance (w): 100.0, Withdrawing 100.0, New balance (w): 0.0 Current balance (d): 0.0, Depositing 100.0, New balance (d): 100.0 Current balance (d): 100.0, Depositing 100.0, New balance (d): 200.0 Current balance (w): 200.0, Withdrawing 100.0, New balance (w): 100.0 …… –Reality Current balance (w): 0.0Current balance (d): 0.0, New balance (d): 100.0, New balance (w): -100.0

2 2 Current balance (w): 0.0Current balance (d): 0.0, New balance (d): 100.0, New balance (w): -100.0 Withdraw thread Deposit thread print(“current balance…) // balance=0 newBalance = balance - 100; Reaches the end of its time slice (newBalance=-100, balance=0) Gain a time slice print(“current balance…); // balance=0 newBalance=balance+100 println(“new balance…”); // newBalance=100 balance = newBalance // balance=100 Gain a time slice println(“new balance…”); // newBalance=-100 balance = newBalance // balance=-100

3 3 Current balance (w): 0.0Current balance (d): 0.0, New balance (d): 100.0, New balance (w): -100.0 Withdraw thread Deposit thread print(“current balance…) // balance=0 newBalance = balance - 100; Reaches the end of its time slice (newBalance=-100, balance=0) Gain a time slice print(“current balance…); // balance=0 newBalance=balance+100 println(“new balance…”); // newBalance=100 balance = newBalance // balance=100 Gain a time slice println(“new balance…”); // newBalance=-100 balance = newBalance // balance=-100 newBalance and balance should have been synchronized.

4 4 ThreadUnsafeBankAccount2 –Removed a local variable (newBalance) from ThreadUnsafeBankAccount to remove a risk to fail data synchronization between balance and newBalance –Output Current balance (d): 0.0, New balance (d): 100.0 Current balance (w): 100.0, New balance (w): 0.0 Current balance (d): 0.0, New balance (d): 100.0 Current balance (w): 100.0, New balance (w): 0.0 Current balance (d): 0.0Current balance (w): 0.0, New balance (w): -100.0, New balance (d): 100.0

5 5 Current balance (d): 0.0Current balance (w): 0.0, New balance (w): -100.0, New balance (d): 100.0 Deposit thread Withdraw thread print(“current balance…) // 0 balance+100 // --> 100 Reaches the end of its time slice (balance=0) Gain a time slice print(“current balance…); // 0 balance = balance - amount; // balance=-100 println(“new balance…); // -100 Reaches the end of its time slice (balance=-100) Gain a time slice balance = 100; println(“new balance…); // balance=100

6 6 Current balance (d): 0.0Current balance (w): 0.0, New balance (w): -100.0, New balance (d): 100.0 Deposit thread Withdraw thread print(“current balance…) // 0 balance+100 // --> 100 Reaches the end of its time slice (balance=0) Gain a time slice print(“current balance…); // 0 balance = balance - amount; // balance=-100 println(“new balance…); // -100 Reaches the end of its time slice (balance=-100) Gain a time slice balance = 100; println(“new balance…); // balance=100 Balance should have been synchronized between threads.

7 7 All threads –Run in their race to complete their tasks. –Manipulate a shared object/data. The end result depends on which of them happens to win the race. –No guarantees on the order of thread execution. –No guarantees on the end result on shared data.

8 8 Thread Synchronization Synchronizing threads, or synchronizing object/data access –Serialized/atomic access to a shared object/data Atom: the smallest possible unit of matter; unable to be broken into separate parts Atomic code: cannot be interrupted during its execution. Any intermediate result/state cannot be revealed to other entities. –Atomic { a = 0; a = a + 3 }

9 9Lock Lock –Used to control the threads that want to manipulate a shared resource data/object. –java.util.concurrent.locks.Lock interface ReentrantLock class: most commonly-used lock class –A lock is added to a class whose methods access a shared data/object. –Atomic code is surrounded by lock() and unlock() method calls. aLock = new ReentrantLock(); aLock.lock(); atomic code aLock.unlock();

10 10 When a thread calls lock(), –it owns the lock until it calls unlock(). –No other threads cannot execute atomic code. –It is guaranteed to execute all atomic code before calling unlock(). If a thread calls lock() when another thread owns the lock, –it goes to the blocked state.

11 11 Runnable Blocked new New start() I/O op completion or thread sync done I/O operation or wait for thread sync (lock) Terminated Exits run() or Explicit thread termination Waiting sleep() join() wait() await() notify() notifyAll() signalAll() interruption Timed Waiting sleep() join() wait() await() notify() notifyAll() signalAll() interruption

12 12 The thread scheduler –Periodically reactivates each blocked thread so that it can acquire a target lock. If the lock is still unavailable, the thread is again blocked. –Notifies the completion of atomic code to waiting threads. Choose one of the waiting thread to acquire the lock. Eventually, when the target lock is available, the waiting thread can acquire the lock.

13 13 A Locking Idiom Call unlock() in a finally clause. –aLock = new ReentrantLock(); aLock.lock(); try { atomic code } finally { aLock.unlock(); } If atomic code throws an exception, unlock() is never called. –A deadlock occurs. Atomic code is locked forever, and nobody can acquire the lock to execute the atomic code.

14 14ThreadSafeBankAccount Output –Lock obtained –Current balance (d): 0.0, New balance (d): 100.0 –Lock released –Lock obtained –Current balance (w): 100.0, New balance (w): 0.0 –Lock released –Lock obtained –Current balance (d): 0.0, New balance (d): 100.0 –Lock released –Lock obtained –Current balance (w): 100.0, New balance (w): 0.0 –Lock released

15 15 Nested Locking class BankAccount { private double balance; private ReentrantLock lock; public void deposit(double amount) { lock.lock(); balance += amount; if (balance < MIN_BALANCE) subractPenaltyFee(); lock.unlock(); } private void subractPenaltyFee() { balance -= PENALTY; } }

16 16 class BankAccount { private double balance; private ReentrantLock lock; public void deposit(double amount){ lock.lock(); balance += amount; notifyCustomer(this); lock.unlock(); } public void notifyCustomer(BankAccount account){ customer.notify(account); } public double getBalance(){ return balance; } } class Customer{ public void notify(BankAccount account){ System.out.print( account.getBalance() ); }

17 17 class BankAccount { private double balance; private ReentrantLock lock; public void deposit(double amount) { lock.lock(); balance += amount; if (balance < MIN_BALANCE) subractPenaltyFee(); lock.unlock(); } public void subractPenaltyFee() { lock.lock(); balance -= PENALTY; lock.unlock(); } }

18 18 class BankAccount { private double balance; private ReentrantLock lock; public void deposit(double amount) { System.out.println(lock.getHoldCount()); lock.lock(); balance += amount; System.out.println(lock.getHoldCount()); if (balance < MIN_BALANCE) subractPenaltyFee(); lock.unlock(); System.out.println(lock.getHoldCount());} public void subractPenaltyFee() { lock.lock(); System.out.println(lock.getHoldCount()); balance -= PENALTY; lock.unlock(); System.out.println(lock.getHoldCount()); }

19 19 class BankAccount { private double balance; private ReentrantLock lock; public deposit(double amount) { lock.lock(); try { balance += amount; if (balance < MIN_BALANCE) subractPenaltyFee(); finally { lock.unlock(); assert lock.getHoldCount()==0: “ERROR” } } public subractPenaltyFee() { balance -= PENALTY; }


Download ppt "1 Race Conditions When threads share access to a common object/data, they can conflict with each other and mess up the consistency of the object/data."

Similar presentations


Ads by Google