1 / 28

Practice Session 7

Practice Session 7. Synchronization Liveness Deadlock Starvation Livelock Guarded Methods Model Thread Timing Busy Wait Sleep and Check Wait and Notify. Synchronization. A mechanism that allows safe access to shared resources . Java provides 3 ways to define synchronized blocks:

salaam
Download Presentation

Practice Session 7

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. Practice Session 7 Synchronization Liveness 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. • Java provides 3 ways to define synchronized blocks: • Synchronized instance method • All the statements in the method become the synchronized block. • All synchronized methods of the same object / synchronized blocks with that object are locked. • The instance object is the lock. • Synchronized Block • A block of code that is part of a method. • All the statements specified in the parentheses of the synchronized statement become the synchronized block, • The object specified in the statement is the lock.

  3. Synchronized examples • Synchronized Instance Method: class Counter { public synchronized void increment() { //this function is locked for an instance of object. x++; } } • Synchronized Statement: class Counter { Object a = new Object(); public synchronized void increment() { //this function is locked for an instance of object. x++; } public void increment2() { //this function can be accessed by all threads at any time. //non safe code can be put here synchronized (a) { //instance of the object is locked when this block is accessed. x++; } } }

  4. Example1 A a = new A(); Thread t1 = new Thread(new B(a)); Thread t2 = new Thread(new B(a)); t1.start(); t2.start(); public class A{ public void fun1(){…} public void fun2(){…} public synchronized void fun3(){….} public synchronized void fun4(){….} } public class B implements Runnable{ private A a; B(A a){ this.a = a;} void run(){ 1. a.fun1(); 2. a.fun3(); 3. synchronized(a){ 4. a.fun2(); 5. } } } 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 B(new A())); Thread t2 = new Thread(new B(new A())); t1.start(); t2.start(); public class A{ public void fun1(){…} public void fun2(){…} public synchronized void fun3(){….} public synchronized void fun4(){….} } public class B implements Runnable{ private A a; B(A a){ this.a = a;} void run(){ 1. a.fun1(); 2. a.fun3(); 3. synchronized(a){ 4. a.fun2(); 5. } } } can be running any line can be running any line can be running any line can be runningany line

  6. Example3 public class B2 implements Runnable{ private A a; B(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(); 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; B(A a){ this.a = a;} void run(){ 1. a.fun1(); 2. a.fun3(); 3. synchronized(a){ 4. a.fun2(); 5. } } } can be runningany line running line: 2, 3 blocked at line: 1 running line: 2, 3 blocked at line: 1 can be runningany 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 ) { //instance of the object is locked when this block is accessed. x++; } } }

  8. Example public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } t1 - > t2 - > t2 - > t2 - > t2 - > t2 - >

  9. Example public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } t2 - > t2 - > t1 - > t2 - > t2 - > t2 - >

  10. Example public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } t2 - > t2 - > t1 - > t2 - >

  11. Example public class B implements Runnable{ private Object fLock; B(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } public class A implements Runnable{ private Object fLock; A(Object lock){fLock = lock;} void run(){ <some commands> synchronized(fLock){ <some commands> } <some commands> } } t2 - > t2 - > t2 - > t2 - > t1 - > t2 - >

  12. Good to Know – Class Level Synchronization • Each object can have two locks: an instance lock, and a class lock, and they are two different locks! • All the statements in the method/code block become the synchronized block. • The classitselfis the lock. • Synchronized Class function (static): class Counter { publicstatic synchronized void increment() { x++; } } • Synchronized Block: Synchronized(Counter.class){ <commands> }

  13. Example Thread t1 = new Thread(new B1(new A())); Thread t2 = new Thread(new B1(new A())); t1.start(); t2.start(); 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 B1 implements Runnable{ private A a; B(A a){ this.a = a;} void run(){ 1. a.fun1(); • a.fun3(); • A.fun5(); 4. synchronized(a){ 5. a.fun2(); • } 7. synchronized(A.class){ 8. a.fun4(); 9. } } } 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 runningany line can be running line: 1,2,4,5,6 Blocked at line: 3, 7

  14. Liveness • Definition: • 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 Thread 1 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 2 acquire Printer acquire Scanner use printer use scanner release Printer release Scanner Thread 1 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 • 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. Thread Timing • Running threads in a specified order. • Enforce order within a group of threads. • How? • The group of threads is split into sub groups. • Order of sub groups is enforced. • Only when first sub group of threads finishes running, • the next one is allowed to run.

  24. Thread Timing Example • Main works through a shared object, called: checkerObject • checkerObject handles the order of thread execution. • Done by assigning numbers for each thread. • Each thread complying to specific number is allowed to run. • Once all of them are done working • checkerObject increments the number value. • Example: • Order of execution: {T1, T2, T3} -> {T4, T5} -> {T6} • First group is assigned #1, 2nd group is assigned #2, and the last one is assigned #3. • Using the checkerObject we maintain order of thread execution.

  25. 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. • 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. • Wait and Notify • Requires communication between threads. • A thread waitsuntil 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. Examples: Threads01, Threads02, Threads03

  26. Busy Wait Example public class A implements Runnable{ private booleanfShouldRun; A(boolean flag){ fShouldRun = flag; } void run(){ while(!fShouldRun); <some commands> } }

  27. Sleep & Wait Example public class A implements Runnable{ private booleanfShouldRun; A(boolean flag){ fShouldRun = flag; } void run(){ while(!fShouldRun){ try{ Thread.sleep(100); }catch( InterruptedException e){ } <some commands> } }

  28. Wait & Notify Example public class A implements Runnable{ private booleanfShouldRun; private Object fDummyObject; A(boolean flag, Object dummyObject){ fShouldRun = flag; fDummyObject = dummyObject; } void run(){ while(!fShouldRun){ try{ fDummyObject.wait(); }catch( InterruptedException e){ } <some commands> } } public class B implements Runnable{ private Object fDummyObject; B(Object dummyObject){ fShouldRun = flag; fDummyObject = dummyObject; } void run(){ <some commands> fDummyObject.notifyAll(); } }

More Related