Download presentation
Presentation is loading. Please wait.
Published byShanon Morrison Modified over 9 years ago
1
Practice Session 7 Synchronization Liveness Guarded Methods Model
Deadlock Starvation Livelock Guarded Methods Model Thread Timing Busy Wait Sleep and Check Wait and Notify
2
Synchronization A mechanism that allows safe access to shared resources. If the method is synchronized, the thread that’s going to run it needs to ask permission to do so from this. Only one thread can have this permission at any given time. Threads accessing non-synchronized methods do not need permission from this. Java provides 2 ways to define synchronized blocks: Synchronized instance method All the statements in the method become the synchronized block. Synchronized Block A block of code that is part of a method.
3
Synchronized examples
Synchronized Instance Method: class Counter { public synchronized void increment() { x++; } Synchronized Statement: public void increment() { //this function can be accessed by all threads at any time. //non safe code can be put here synchronized (this) { //threads need permission from this to access this code block
4
Example1 A a = new A(); Thread t1 = new Thread(new B1(a));
public class A{ public void fun1(){…} public void fun2(){…} public synchronized void fun3(){….} public synchronized void fun4(){….} } public class B1 implements Runnable{ private A a; B1(A a){ this.a = a;} void run(){ 1. a.fun1(); 2. a.fun3(); 3. synchronized(a){ 4. a.fun2(); 5. } A a = new A(); Thread t1 = new Thread(new B1(a)); Thread t2 = new Thread(new B1(a)); t1.start(); t2.start(); t1 running line 1 running line 2 running line 3,4 done with line 5 t2 can be running any line running line 1 blocked at line: 2, or 3 running line 1 blocked at line: 2 or 3 can be running any line
5
Example2 Thread t1 = new Thread(new B1(new A()));
public class A{ public void fun1(){…} public void fun2(){…} public synchronized void fun3(){….} public synchronized void fun4(){….} } public class B1 implements Runnable{ private A a; B1(A a){ this.a = a;} void run(){ 1. a.fun1(); 2. a.fun3(); 3. synchronized(a){ 4. a.fun2(); 5. } Thread t1 = new Thread(new B1(new A())); Thread t2 = new Thread(new B1(new A())); t1.start(); t2.start(); t1 running line 1 running line 2 running line 3,4 done with line 5 t2 can be running any line can be running any line can be running any line can be running any line
6
Example3 A a = new A(); Thread t1 = new Thread(new B1(a));
public class A{ public void fun1(){…} public void fun2(){…} public synchronized void fun3(){….} public synchronized void fun4(){….} } public class B1 implements Runnable{ private A a; B1(A a){ this.a = a;} void run(){ 1. a.fun1(); 2. a.fun3(); 3. synchronized(a){ 4. a.fun2(); 5. } public class B2 implements Runnable{ private A a; B2(A a){ this.a = a;} void run(){ 1. a.fun4(); a.fun1(); a.fun2(); } A a = new A(); Thread t1 = new Thread(new B1(a)); Thread t2 = new Thread(new B2(a)); t1.start(); t2.start(); t1 running line 1 running line 2 running line 3,4 done with line 5 t2 can be running any line running line: 2, 3 blocked at line: 1 running line: 2, 3 blocked at line: 1 can be running any line
7
Blocking using a Dummy Object
Used to synchronize code blocks found in different objects of different types. class Counter { private Object myLock = new Object(); public void increment() { //this function can be accessed by all threads at any time. //non safe code can be put here synchronized (myLock ) { //threads accessing this code block need permission from myLock to do so x++; }
8
Example public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } t1 - > t2 - > t2 - > t2 - > t2 - > t2 - >
9
Example public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } t2 - > t1 - > Blocked t2 - > t2 - >
10
Example public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(lock){ <some commands> } public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(lock){ <some commands> } t2 - > t2 - > t1 - > t2 - >
11
Example public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } t2 - > t2 - > t2 - > t2 - > t1 - > t2 - >
12
Good to Know – Class Level Synchronization
All the statements in the method/code block become the synchronized block. Threads accessing a static synchronized method need permission from the class. Only one thread is given that permission at any given time. Synchronized Class function (static): class Counter { public static synchronized void increment() { x++; } Another way to ask permission from the class: Synchronized Block: synchronized(Counter.class){ <commands>
13
Example Thread t1 = new Thread(new B(new A()));
public class A{ public void fun1(){…} public void fun2(){…} public synchronized void fun3(){….} public synchronized void fun4(){….} public static synchronized void fun5(){…} public static synchronized void fun6(){…} } public class B implements Runnable{ private A a; B(A a){ this.a = a;} void run(){ 1. a.fun1(); a.fun3(); A.fun5(); 4. synchronized(a){ a.fun2(); 7. synchronized(A.class){ 8. a.fun4(); 9. } Thread t1 = new Thread(new B(new A())); Thread t2 = new Thread(new B (new A())); t1.start(); t2.start(); t1 running line 1 running line 2 running line 3 running line 4-6 running line 7-9 t2 can be running any line can be running any line can be running line: 1,2, 4,5,6 Blocked at: 7, 3 can be running any line can be running line: 1,2,4,5,6 Blocked at line: 3, 7
14
Liveness Definition: Liveness problems:
A concurrent application's ability to execute in a timely manner is known as its liveness. Liveness problems: Deadlock Starvation Livelock
15
Deadlock Traffic Jam Dining Philosophers
(all of them take the left fork at the same time, then try to take the left one). Device allocation: process 1 requests HD and gets it process 2 requests DVD drive and gets it process 1 requests DVD drive but is blocked process 2 requests HD but is blocked Infinite wait! (Code Example - eclipse!)
16
Deadlock Solution Solution? Resource Ordering! Thread 1 Thread 2
acquire Printer acquire Scanner use printer use scanner release Printer release Scanner Thread 2 acquire Scanner acquire Printer use scanner use printer release Scanner release Printer Solution? Resource Ordering! All threads must acquire the locks in the same order! Thread 1 acquire Printer acquire Scanner use printer use scanner release Printer release Scanner Thread 2 acquire Printer acquire Scanner use printer use scanner release Printer release Scanner
17
Starvation Some threads are waiting forever for resources that are used by other threads. Example: dining philosophers 2,4 eat always 1,3,5 never get the chance! 3 2 4 1 5
18
Starvation A task will starve if it ceases to make progress in the presence of others. Example: Priority scheduling Each thread has priority level: low, high. Low priority threads execute only if there are no high priority threads. Problem: High priority threads keep coming. Low priority threads never get the chance to run!
19
Livelock Threads are unable to make progress although they are not blocked. Task enters infinite loop of operations that lead to nothing. Example: Lock device 1 Attempt to lock memory resource, fail Release device 1 Retry
20
Livelock - Example A husband and wife eating at a restaurant
they are sharing a fork. they won't eat unless they are sure the other one has eaten first. Result - livelock: The wife takes the fork, checks if the husband has eaten, returns the fork. (same with the husband).
21
Deadlock, Livelock, Starvation
Deadlocks/livelocks rarely happen. Deadlocks/livelocks lead to thread starvation. Starvation is not limited to deadlocks/livelocks only: A thread might wait infinitely for a resource to be released, this might happen when higher priority threads keep getting access to such a resource. A thread might not get to run at all due to its low priority.
22
Guarded Methods Model Definition How is it done?
The guarded method model delays the execution of a thread until a condition is satisfied. A thread that is unable to proceed, waits for condition change made by another thread. How is it done? Busy Wait Sleep and Check Wait and Notify
23
How to check if a thread allowed to run?
Busy Waiting Each thread constantly checks whether the condition is met. Done using a loop. This results in heavy CPU usage. Not recommended. Special cases: Waiting time will be very small. It is critical to instantly react when the condition is met.
24
Busy Wait - CounterExample
public static void main(String[] a) { for (int i=0;i<10;i++){ // create our shared object Counter ctr = new Counter(); // send same unprotected object to two different threads Thread t1 = new Thread(new Incrementer(ctr)); Thread t2 = new Thread(new Incrementer(ctr)); //start running the two threads t1.start(); t2.start(); //wait until their job is done while (t1.isAlive() || t2.isAlive()); //wait until all done. //print out result of attempt i System.out.println("Attempt " + i + ", ctr1 value: " + ctr.getValue()); }
25
Sleep and Check Similar to busy wait, but with the addition of sleep interval after each check. Uses much less CPU cycles. Disadvantage: delay in reaction when the condition is met.
26
Sleep & Wait Example public static void main(String[] a) {
for (int i=0;i<10;i++){ Counter ctr = new Counter(); Thread t1 = new Thread(new Incrementer(ctr)); Thread t2 = new Thread(new Incrementer(ctr)); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()){//wait until all done. try{ Thread.sleep(100); }catch(InterruptedException e){ } System.out.println("Attempt " + i + ", ctr1 value: " + ctr.getValue());
27
Wait and Notify Requires communication between threads.
A thread waits until some condition occurs. Some other thread can then notify the waiting thread, to continue its execution. Once the thread is notified, it validates the condition again. This is because multiple threads might be waiting for notification. You must synchronize the object before waiting on it. If you wish to notify threads waiting on an object you must synchronize it first.
28
Wait & Notify Example public class Incrementer implements Runnable {
public static void main(String[] a) { for (int i=0;i<10;i++){ Counter ctr = new Counter(); Thread t1 = new Thread(new Incrementer(ctr)); Thread t2 = new Thread(new Incrementer(ctr)); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()){ try { synchronized(ctr){ ctr.wait(); } Thread.sleep(100);//give the threads time to die //after they activated notifyAll } catch (InterruptedException e) { e.printStackTrace(); System.out.println("Attempt " + i + ", ctr1 value: " + ctr.getValue()); public class Incrementer implements Runnable { Counter fCounter; Incrementer(Counter ctr) { fCounter = ctr; } public void run() { for (int i = 0; i<200; i++) { fCounter.increment(); synchronized (fCounter){ fCounter.notifyAll();
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.