Presentation is loading. Please wait.

Presentation is loading. Please wait.

Multithreading : synchronization. Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.2 Solving the Race Condition Problem A thread must.

Similar presentations


Presentation on theme: "Multithreading : synchronization. Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.2 Solving the Race Condition Problem A thread must."— Presentation transcript:

1 Multithreading : synchronization

2 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.2 Solving the Race Condition Problem A thread must be able to lock an object temporarily When a thread has the object locked, no other thread can modify the state of the object. In Java, use synchronized methods to do this Tag all methods that contain thread-sensitive code with the keyword synchronized

3 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.3 Synchronized Methods public class BankAccount { public synchronized void deposit(double amount) {... } public synchronized void withdraw(double amount) {... }... }

4 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.4 With synchronization, the final balance is always correct!

5 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.5 Synchronized Methods By declaring both the deposit and withdraw methods to be synchronized  Our program will run correctly  Only one thread at a time can execute either method on a given object  When a thread starts one of the methods, it is guaranteed to execute the method to completion before another thread can execute a synchronized method on the same object.

6 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.6 By executing a synchronized method:  The thread acquires the object lock.  No other thread can acquire the lock.  No other thread can modify the state of the object until the first thread is finished. Every object in Java has a lock associated with it. Every object can maintain a list of waiting threads.

7 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.7 Visualization of Synchronized Thread Behavior Imagine the object is a restroom that only one person can use at a time The threads are people If the restroom is empty, a person may enter If a second person finds the restroom locked, the second person must wait until it is empty If multiple people want to gain access to the restroom, they all wait outside The people may not form an orderly queue A randomly chosen person may gain access when the restroom becomes available again

8 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.8 Deadlock A deadlock occurs if no thread can proceed because each thread is waiting for another to do some work first. In other words, a deadlock occurs when two threads end up waiting for each other to release a lock they need. Since neither one can proceed, neither one can release the lock it holds, and they both stop running. When you are synchronizing threads, you must be careful to avoid deadlock.

9 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.9 BankAccount example public synchronized void withdraw(double amount) { while (balance < amount) //wait for balance to grow... }

10 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.10 The method can lead to deadlock The thread sleeps to wait for balance to grow, but it still has the lock No other thread can execute the synchronized deposit method If a thread tries to call deposit, it is blocked until the withdraw method exits withdraw method can't exit until it has funds available DEADLOCK occurs!

11 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.11 Avoiding Deadlock The wait method temporarily releases the object lock and deactivates the thread Restroom analogy  Don't want the person in the restroom to go to sleep if there is no toilet paper.  Think of the person giving up and leaving  This gives another person a chance to enter and refill the toilet paper

12 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.12 withdraw Method to Avoid Deadlock with wait() public synchronized void withdraw(double amount) throws InterruptedException { while (balance < amount) wait();... }

13 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.13 Wait and NotifyAll A thread that calls wait is in a blocked state It will not be activated by the thread scheduler until it is unblocked It is unblocked when another thread calls notifyAll When a thread calls notifyAll, all threads waiting on the object are unblocked Only the thread that has the lock can call notifyAll

14 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.14 Restroom wait/notifyAll Analogy The thread calling wait() corresponds to the person who enters the restroom and finds there is no toilet paper The person then leaves the restroom and waits outside Other people may enter and leave, but the first person just waits Eventually an attendant enters the restroom, refills the toilet paper, and shouts a notification All the waiting people compete for the restroom

15 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.15 File BankAccountThreadTest.java (Modified, Using synchronized methods) /** This program runs four threads that deposit and withdraw money from the same bank account. */ public class BankAccountThreadTest { public static void main(String[] args) {

16 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.16 BankAccount account = new BankAccount(); DepositThread t0 = new DepositThread(account, 100); WithdrawThread t1 = new WithdrawThread(account, 100); DepositThread t2 = new DepositThread(account, 100); WithdrawThread t3 = new WithdrawThread(account, 100); t0.start(); t1.start(); t2.start(); t3.start(); } //end main } // end class

17 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.17 File BankAccount.java (modified) /** A bank account has a balance that can be changed by deposits and withdrawals. */ public class BankAccount { /** Constructs a bank account with a zero balance */ public BankAccount() { balance = 0; } /** Deposits money into the bank account. @param amount the amount to deposit */

18 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.18 public synchronized void deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; notifyAll(); } /** Withdraws money from the bank account. @param amount the amount to withdraw */ public synchronized void withdraw(double amount) throws InterruptedException { while (balance < amount) wait(); System.out.print("Withdrawing " + amount); double newBalance = balance - amount; System.out.println(", new balance is " + newBalance); balance = newBalance; }

19 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.19 /** Gets the current balance of the bank account. @return the current balance */ public synchronized double getBalance() { return balance; } private double balance; } // end class

20 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.20 Be careful! A common error is to have threads call wait without matching calls to notifyAll by other threads. Whenever you call wait, ask yourself which call to notifyAll will notify your thread. The thread that calls notifyAll must own the lock on the object on which notifyAll is called. Otherwise, an IllegalMonitorStateException is thrown.

21 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.21 notify( ) While notifyAll( ) wakes up all threads that are waiting on the object, notify( ) wakes up only a single thread that is waiting on the object. If any threads are waiting on the object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. It's better to use notifyAll( ).

22 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.22 Complex Deadlocks Using the wait and notifyAll methods does not solve all deadlocks. The following is an example. We have three accounts: account0, account1, and account2 ; and three transfer threads: t0, t1, and t2. A transfer thread transfers money from two accounts into a third. t0 repeatedly transfers $500 each from account1 and account2 to account0. t1 repeatedly transfers $500 each from account2 and account0 to account1. t2 repeatedly transfers $500 each from account0 and account1 to account2.

23 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.23 If the three threads take turns and each thread executes one iteration before losing control of the CPU, then the program runs indefinitely: account0account1account2 Initial balance$1000 After t0 iteration$2000$500 After t1 iteration$1500 0 After t2 iteration$1000

24 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.24 But if it happens that t0 executes two iterations before t1 and t2 get a chance, then the program deadlocks: account0account1account2 Initial balance$1000 After t0 iteration$2000$500 After t0 iteration$300000 Now none of the three threads can progress, and a deadlock occurs.

25 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.25 Most of the time, the program will carry out the transfers successfully, but once in a while you may be able to observe a deadlock. Programmers who create multithreaded programs must make an effort to prove rigorously why their threads cannot deadlock no matter in which order they are executed. Running a few experiments is not enough. It can be misleading.

26 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.26 File BankAccountThreadTest.java /** This program uses three threads that transfer money between three accounts. It can occasionally deadlock. */ public class BankAccountThreadTest { public static void main(String[] args) { BankAccount account0 = new BankAccount(1000); BankAccount account1 = new BankAccount(1000); BankAccount account2 = new BankAccount(1000); //... Put your code here... }

27 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.27 File TransferThread.java /** A transfer thread repeatedly transfers money between three bank accounts. */ class TransferThread extends Thread { /** Constructs a transfer thread. @param account1 the first account to withdraw @param account2 the second account to withdraw @param account3 the account to deposit @param anAmount the amount to withdraw from each of the first two accounts. */ public TransferThread(BankAccount account1, BankAccount account2, BankAccount account3, double anAmount) { //... Put your code here... }

28 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.28 public void run() { try { for (int i = 1; i <= REPETITIONS && !isInterrupted(); i++) { //... Put your code here... sleep(DELAY); } catch (InterruptedException exception) { } private BankAccount from1, from2, to; private double amount; private static final int REPETITIONS = 10; private static final int DELAY = 10; }

29 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.29 /** A bank account has a balance that can be changed by deposits and withdrawals. */ public class BankAccount { /** Constructs a bank account with a given balance @param initialBalance the initial balance */ public BankAccount(double initialBalance) { balance = initialBalance; } File BankAccount.java

30 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.30 /** Deposits money into the bank account. @param amount the amount to deposit */ public synchronized void deposit(double amount) { balance = balance + amount; System.out.println(Thread.currentThread().getName() + " Depositing " + amount + ", new balance is " + balance); notifyAll(); }

31 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.31 /** Withdraws money from the bank account. @param amount the amount to withdraw */ public synchronized void withdraw(double amount) throws InterruptedException { while (balance < amount) { System.out.println(Thread.currentThread().getName() + " Waiting..."); wait(); } balance = balance - amount; System.out.println(Thread.currentThread().getName() + " Withdrawing " + amount + ", new balance is " + balance); }

32 Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.32 /** Gets the current balance of the bank account. @return the current balance */ public synchronized double getBalance() { return balance; } private double balance; } //end class


Download ppt "Multithreading : synchronization. Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.2 Solving the Race Condition Problem A thread must."

Similar presentations


Ads by Google