1 / 32

System Programming

System Programming. Practical Session 7. Synchronization, Liveness, Guarded Methods, and Thread Timing. Synchronization. A mechanism allowing safely accessing shared resources. A thread accessing a synchronized method locks the object.

thortone
Download Presentation

System Programming

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. System Programming Practical Session 7 Synchronization, Liveness, Guarded Methods, and Thread Timing

  2. Synchronization A mechanism allowing safely accessing shared resources. A thread accessing a synchronized method locks the object. The object cannot be accessed by other threads while it is locked.

  3. Synchronization 1. Class Even{ 2. privatelong n = 0; 3. publiclongnext(){ 4. n++; 5. n++; 6.returnn; 7. } 8. }

  4. Synchronization 1. Class Even{ 2. privatelong n = 0; 3. publicsynchronizedlongnext(){ 4. n++; 5. n++; 6.returnn; 7. } 8. }

  5. Synchronizing a block • publicintfoo(){ • //dosomething safe • synchronized(this){ • //do something • return9; • } • }

  6. Solution to safety problem Printer Example (from practical session 1) • classPrinter{ • Printer(){} • /** • *@paramilinenumber • *@paramsthestringtoconcatenate 40 times • */ • publicsynchronizedvoidprintALine(inti,Strings){ • System.out.print(i+")"); • for(intj=0;j<40;j++){ • System.out.print(s); • } • System.out.println(); • } • }

  7. publicclassGoodSynchronization{ • publicstaticvoidmain(String[]a){ • Printerp=newPrinter(); • Threadt1=newThread(newSimpleAsynchronousTask("a",p)); • Threadt2=newThread(newSimpleAsynchronousTask("b",p)); • t1.start();//printssomelinesofaaaa • t2.start();//printssomelinesofbbbb • } } • classSimpleAsynchronousTaskimplementsRunnable{ • Printerm_p; • Stringm_name; • publicSimpleAsynchronousTask(Stringname,Printerp){ • m_p=p; • m_name=name; • } • publicvoidrun(){ • for(inti=0;i<50;i++){ • m_p.printALine(i,m_name); • } • } }

  8. Wrong solution #1 • publicclassBadSynchronization2 • publicstaticvoidmain(String[]a){ • Printerp1=newPrinter(); • Printerp2=newPrinter(); • Threadt1=newThread(newSimpleAsynchronousTask("a",p1)); • Threadt2=newThread(newSimpleAsynchronousTask("b",p2)); • t1.start();//printssomelinesofaaaa • t2.start();//printssomelinesofbbbb • } • } • classSimpleAsynchronousTaskimplementsRunnable{ • .....thesamelikeGoodSynchronization.java • classPrinter{ • .....thesamelikeGoodSynchronization.java • }

  9. Wrong solution #2 (no printer object) • classBadSynchronization{ • publicstaticvoidmain(String[]a){ • Threadt1=newThread(newSimpleAsynchronousTask("a")); • Threadt2=newThread(newSimpleAsynchronousTask("b")); • t1.start();//printssomelinesofaaaa • t2.start();//printssomelinesofbbbb • } • } • classSimpleAsynchronousTaskimplementsRunnable{ • .....thesamelikeGoodSynchronization.java • publicsynchronizedvoidprintALine(inti,Strings){ • System.out.print(i+")"); • for(intj=0;j<40;j++)System.out.print(s); • System.out.println(); • } • }

  10. Liveness A concurrent application's ability to execute in a timely manner. • Liveness problems: • Deadlock • Starvation • Livelock

  11. Deadlock Thread 2 acquire Scanner acquire Printer use scanner use printer release Scanner release Printer Thread 1 acquire Printer acquire Scanner use printer use scanner release Printer release Scanner Thread 1 Thread 2

  12. publicclassDeadlock{ • publicstaticvoidmain(String[]args){ • finalObjectresource1=“Printer"; • finalObjectresource2=“Scanner"; • Threadt1=newThread(newRunnable(){ • publicvoidrun(){ • synchronized(resource1){ • System.out.println("Thread1:lockedresource1"); • try{Thread.sleep(50);}catch(InterruptedExceptione){} • synchronized(resource2){ • System.out.println("Thread1:lockedresource2"); • }/* release resource2 */}/* release resource1 */}} ); • Threadt2=newThread(newRunnable(){ • publicvoidrun(){ • synchronized(resource2){ • System.out.println("Thread2:lockedresource2"); • try{Thread.sleep(50);}catch(InterruptedExceptione){} • synchronized(resource1){ • System.out.println("Thread2:lockedresource1"); • }/* release resource1 */}/* release resource2 */}} ); • t1.start();t2.start();} }

  13. Resource Ordering All threads 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

  14. Starvation Some threads are waiting forever for resources that are used by other threads.

  15. Starvation Some threads are waiting forever for resources that are used by other threads. Example1: A solution to the dinning philosophers problem in which philosophers 1,3,5 never eat, and philosophers 2,4 eat whenever they want. 3 2 4 1 5

  16. Starvation Example 2: Threads with priority. Each thread has a priority: Low or High. Low priority threads execute only if there are no high priority threads. High priority threads keep coming. High Low

  17. Livelock Threads are unable to make progress although they are not blocked.

  18. Livelock Threads are unable to make progress although they are not blocked. Example: two threads trying to pass a shared corridor. Thread protocol: if there is an obstacle, then move aside.

  19. Livelock Threads are unable to make progress although they are not blocked. Example: two threads trying to pass a shared corridor. Thread protocol: if there is an obstacle, then move aside.

  20. Guarded Methods 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.

  21. Basic Thread Timing Example Each thread is assigned a number from {1,2,…,k}. In any point in time, only threads assigned a certain number run. Other threads wait. 1 3 1 1

  22. Basic Thread Timing Example Each thread is assigned a number from {1,2,…,k}. In any point in time, only threads assigned a certain number run. Other threads wait. 1 3 3 1

  23. classChecker{ • privateintm_num; • publicChecker(intnum){ • this.m_num=num; • } • publicsynchronizedvoidchange(intnum){ • this.m_num=num; • } • publicsynchronizedbooleancheck(intnum){ • return(num==this.m_num); • } • }

  24. publicclassThreads01{ • publicstaticvoidmain(String[]args){ • CheckercheckerObject=newChecker(0); • Thread t[] = new Thread[9]; • for (int i = 0; i < t.length ; i++) • t[i] = new Thread(new SleepThread(i/3+1, "NO. " +(i+1)+ • " done, was waiting for "+(i/3+1), checkerObject)); • for (int i = 0; i < t.length; i++) • t[i].start(); • try{Thread.sleep(1000); • checkerObject.change(1); • Thread.sleep(1000); • checkerObject.change(3); • Thread.sleep(1000); • checkerObject.change(2); • }catch(InterruptedExceptione){} • } • }

  25. Solution #1: Busy Waiting • classSleepThreadimplementsRunnable{ • privateintm_num; • privateStringm_strToPrintWhenDone; • privateCheckerm_checkerObject; • SleepThread(intnum,StringstrToPrintWhenDone,CheckercheckerObject){ • this.m_num=num; • this.m_strToPrintWhenDone=strToPrintWhenDone; • this.m_checkerObject=checkerObject; • } • publicvoidrun(){ • /* busy waiting*/ • while(!this.m_checkerObject.check(this.m_num)) • ; • System.out.println(this.m_strToPrintWhenDone); • } • }

  26. Solution #2: Sleep and Check • classSleepThreadimplementsRunnable{ • privateintm_num; • privateStringm_strToPrintWhenDone; • privateCheckerm_checkerObject; • SleepThread(intnum,StringstrToPrintWhenDone,CheckercheckerObject){ • this.m_num=num; • this.m_strToPrintWhenDone=strToPrintWhenDone; • this.m_checkerObject=checkerObject; • } • publicvoidrun(){ • while(!this.m_checkerObject.check(this.m_num)) • { • try{ • Thread.sleep(100); • }catch(InterruptedExceptione){} • } • System.out.println(this.m_strToPrintWhenDone); • } • }

  27. Solution #3: Wait and Notify • classSleepThreadimplementsRunnable{ • ……… • publicvoidrun() • { • this.m_checkerObject.returnWhenCheckIsTrue(m_num); • System.out.println(m_strToPrintWhenDone); • }} • classChecker{ • privateintm_num; • publicChecker(intnum){this.m_num=num;} • publicsynchronizedvoidchange(intnum){ • this.m_num=num; • this.notifyAll(); • } • publicsynchronizedvoidreturnWhenCheckIsTrue(intnum){ • while(num!=m_num){ • try{ • this.wait(); • }catch(InterruptedExceptione){} • } • } }

  28. Tips • Use a while loop (and not an if condition) to check the precondition • notify() Vs. notifyAll() - which of them should you use? • When calling wait(), notifyAll() or notify() on an object, make sure the calling thread holds the object's lock. Notice that if you do not hold the object's lock you will receive an illegal monitor runtime exception. • After performing a wait call on the object, the thread releases the object's lock. Furthermore, before exiting the wait set of the object, the thread must re-lock the object • A thread that releases an object's, lock will NOT release other locks it has

  29. Advanced Synchronization Tools CountDownLatch • Constructor: • CountDownLatch(int value) • Methods: • void countDown() • Decrements the latch value by 1. • void await() • Causes the current thread to wait until the latch has counted down to zero.

  30. importjava.util.concurrent.*; • publicclassThreads{ • publicstaticvoidmain(String[]args) • { • CountDownLatchlatchObject=newCountDownLatch(3); • Servers=newServer(latchObject); • Clientc1=newClient(1,latchObject); • Clientc2=newClient(2,latchObject); • Clientc3=newClient(3,latchObject); • Threadt1=newThread(s); • Threadt2=newThread(c1); • Threadt3=newThread(c2); • Threadt4=newThread(c3); • t1.start(); • t2.start(); • t3.start(); • t4.start(); • } • }

  31. classServerimplementsRunnable{ • privateCountDownLatchm_latchObject; • publicServer(CountDownLatchlatchObject) • { • m_latchObject=latchObject; • } • publicvoidrun() • { • synchronized(System.out) • { • System.out.println("Serverinitialized"); • } • try{ • m_latchObject.await(); • }catch(InterruptedExceptione) • { • return; • } • System.out.println("Serverfinished"); • } • }

  32. classClientimplementsRunnable{ • privateintm_id;privateCountDownLatchm_latchObject; • publicClient(intid,CountDownLatchlatchObject){ • m_id=id; • m_latchObject=latchObject; • } • publicvoidrun(){ • synchronized(System.out){ • System.out.println("Client#"+m_id+"started"); • } • try{Thread.sleep(200); }catch(InterruptedExceptione){} • synchronized(System.out){ • System.out.println("Client#"+m_id+"doingsomething"); • } • try{Thread.sleep(200); }catch(InterruptedExceptione){} • synchronized(System.out){ • System.out.println("Client#"+m_id+"finished"); • } • m_latchObject.countDown(); • } • }

More Related