1 / 64

Counting Semaphore Implementation in Java

Counting Semaphore Implementation in Java. CS598 – Concurrent Programming. Kasturi Kallakuri Cindy Mayo 21 August 2002. “Alfonse, Wait Here for My Signal!”. Author: Stephen J. Hartley Original presentation: ACM-SIGCSE March 1999 New Orleans, Louisiana. 1 Java is Multithreaded.

Download Presentation

Counting Semaphore Implementation in Java

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.


Presentation Transcript

  1. Counting SemaphoreImplementation in Java CS598 – Concurrent Programming Kasturi Kallakuri Cindy Mayo 21 August 2002

  2. “Alfonse, Wait Herefor My Signal!” Author: Stephen J. Hartley Original presentation: ACM-SIGCSE March 1999 New Orleans, Louisiana

  3. 1 Java is Multithreaded • The Java Virtual Machine can support many threads of execution at a time • A thread is a separate flow of control within a program • Each thread has its own local variables and lifetime

  4. 1 Java is Multithreaded • All threads within a program share the same address space • Thread is represented by the Java Thread class • Threads can be synchronized with other threads in same process

  5. 1.1 A Multithreaded Program P R O G R A M Threads HotJava Web Browser is an example of a multithread Java application

  6. 1.2 Thread Creation • Implement the Runnable Interface • Subclass (extend) the Thread class

  7. 1.2.1 Implementing Runnable class HelloRunnable implements Runnable{ public void run() { System.out.println(“Hello World!”);} } HelloRunnable hr = new HelloRunnable(); Thread hThread = new Thread(hr); hThread.start()

  8. 1.2.2 Subclassing Thread class HelloThread extends Thread{ public void run( { System.out.println(“HelloWorld!”); } } HelloThread hThread = new HelloThread(); hThread.start()

  9. running blocked sleeping waiting ready dead born 1.3 Life Cycle of a Thread start() notify() notifyAll() I/O completion quantum expiration “yield” interrupt dispatch issue I/O request wait() complete sleep() sleep interval expires

  10. 1.4 Thread Priorities • By default, all threads have equal priority • setPriority() can be used to change the default priority • Java implements MIN_PRIORITY (0) and MAX_PRIORITY (10) • Microsoft’s JVM utilizes time slicing • Solaris’ JVM does not

  11. 2 Object Locks • Every Java Object has a lock, which is implemented as a binary semaphore • Java supports mutual exclusion through the synchronized keyword • Object locks may be class locks or class instance locks.

  12. 2 Object Locks • Java does not provide a way to perform separate locking and unlocking functions • lock() and unlock() are implicitly performed by high-level constructs that arrange ways to pair such actions correctly • The JVM provides separate monitorenter and monitorexit instructions that implement the lock and unlock actions

  13. 2.1 Mutual Exclusion • Synchronized blocks • Synchronized methods

  14. 2.1.1 Synchronized block • Acquires the object lock before executing the body of the synchronized block • After execution of the block, unlocks the lock • Syntax: Object obj = new Object(); synchronized (obj) { // critical section }

  15. 2.1.1 Synchronized block class Update { private int data = 0; public void increment(){ synchronized(this) { //lock the object data++; } }//end of increment } //end of class

  16. 2.1.2 Synchronized method • Automatically performs lock action when invoked • After execution of the method’sbody,unlock action is automatically performed on same lock • Syntax: Object obj = new obj();//methods use synchronized type method(…){ //body of method }

  17. 2.1.2 Synchronized method • bump() uses an instance lock (this) • classBump() uses the class lock class Test { int count; static int classCount; synchronized void bump() { count++; } static synchronized void classBump() { classCount++; } }

  18. 2.2 ConditionalSynchronization • Waiting process should leave the semaphore but not exit the method • Leaving the object instance releases the lock • Instances need back porch where waiters leave and not exit the instance. [wait set] • There is only one wait set per class instance

  19. 2.2 Conditional Synchronization • Object method wait() blocks calling thread in wait set. • Object method notify() unblocks a thread if any in the wait set • Object method notifyAll() unblocks all threads in the wait set.

  20. 2.3 Deadlock • Java does not prevent, nor require detection of deadlock conditions • Programs where threads hold locks on multiple objects should use conventional techniques for avoiding deadlock • Create higher level locking primitives that cannot deadlock, if necessary

  21. 2.3.1 Mutex behaviour • Mutex unblocking is arbitary • Thread priority is ignored • Thread starvation is possible • Mutex locking is re-entrant • A thread can relock any mutex it holds

  22. 2.3.2 Interference • Interference with conditional synchronization • Unblocked thread may not immediately regain the mutex • The signaled condition may no longer be true when it does

  23. 2.4 Points to Remember • The acquisition and release of locks is done automatically and atomically by the Java Virtual Machine (JVM), which guarantees that: • Race conditions cannot occur • Data integrity is ensured Mutex behaviour needs to be worked around

  24. 3 Java Monitors • Monitors are a data abstract mechanism • Monitors encapsulate data without external access and references outside of the monitor are blocked • Monitors contain variables that store the object’s state and procedures that implement operations on the object

  25. 3 Java Monitors • Mutual exclusion is provided implicitly by ensuring that procedures in the same monitor are not executed concurrently • Condition synchronization is provided explicitly by condition variables

  26. 3.1 Java Monitor Structure class Monitor { private .. //data fields Monitor(..){…} //constructor synchronized type method1(){ notifyAll(); while ( !condition ) try { wait(); } catch(InterruptedException e){} notifyAll(); } Note: Monitors are compile time entities

  27. 3.2 Concurrency Control • Mutual Exclusion • Conditional Synchronization

  28. 3.2.1 Mutual Exclusion • A monitor procedure is called by an external process • At most, one instance of monitor procedure may be active at a time • Only one thread at a time is allowed inside the monitor

  29. 3.2.1 Mutual Exclusion • Monitor entries are (java) synchronized always. • Monitor procedures by definition execute with mutual exclusion • It is up to the language and operating system to provide mutual exclusion

  30. 3.2.2 Condition Synchronization • A condition variable is used to delay a process that cannot safely continue executing until the monitor’s state satisfies some Boolean condition • There may be many condition variables per monitor • Monitor’s back porch

  31. 3.2.2 Condition Synchronization • A process queries the state of a condition variable by calling empty() • A process blocks on a condition variable by calling wait() • Processes blocked on a condition variable are awakened by a call to signal()

  32. Condition variable queue Executing in monitor Entry queue 3.3 Signal and Continue Signal and continue wait() monitor free call return

  33. 3.3 Signal and Continue • Signal and continue is non preemptive • Condition variable release is FIFO • Relation between signaled and signaler: • Signaled jumps to the front of the entry queue signaler continues

  34. 3.4 Perils of Monitors • The thread blocked longest on a monitor synchronized method call is not guaranteed to be next thread to acquire the monitor lock when the monitor lock is released

  35. 3.4 Perils of Monitors • The thread blocked the longest in a wait() call is not guaranteed to be the one removed from the wait set when a notify() call is made • Typically, FIFO is used to determine who gets control (JVM/platform specific)

  36. 3.4 Perils of Monitors • A thread waiting for the monitor lock to execute a monitor synchronized method might get the lock before a signaled thread reacquires the lock even if the notify occurred earlier than the monitor method call • A thread should always recheck its wait condition when signaled

  37. 3.4 Perils of Monitors • The while construct is preferred over the if construct while ( !condition ) wait(); notifyAll();

  38. 3.4 Perils of Monitors • Each monitor has a single, nameless condition variable • Cannot specify which of the waiting threads should be released by a notify() call • May need to use notifyAll() to awaken all threads and allow contention

  39. 3.4 Perils of Monitors • sleep(), join(), and wait() throw InterruptedException • No exception is thrown if a thread is interrupted while blocked • An exception is thrown by wait() if a thread that has been notified is interrupted while waiting to reacquire the monitor lock

  40. 3.4 Perils of Monitors • Ignoring InterruptedException with an empty catch block can be acceptable in a while loop while ( !condition ) try { wait(); } catch (InterruptedException e) {} • Must be using notifyAll()

  41. 3.4 Perils of Monitors • Cannot ignore InterruptedException when using an if construct if ( !condition ) try { wait(); } catch (InterruptedException e) {} • Notification slip

  42. 3.4 Perils of Monitors • It is desirable to have the containing method throw the exception back to the calling function so that the calling function knows that an exception has actually occurred

  43. 4 Counting Semaphores • V() operation if threads blocked in P(), unblock one else increment semaphore value • P() operation if semaphore value is 0 block semaphore else decrement semaphore value

  44. 4 Counting Semaphores • Safety • Liveness • Barging • Signaling • Exception propagation

  45. 4.1 First Attempt public class CountingSemaphore { private int value = 0; public CountingSemaphore(int initial) { if ( initial > 0 ) value = initial; }

  46. 4.1 First Attempt public synchronized void P() throws InterruptedException { if ( value = = 0 ) wait(); value--; }

  47. 4.1 First Attempt public synchronized void V() { if (value = = 0) notify(); value++; } } // End of class CountingSemaphore

  48. 4.2 Second Attempt public synchronized void P() throws InterruptedException { while ( value = = 0 ) wait(); value--; }

  49. 4.3 Third Attempt public synchronized void P() throws InterruptedException { value--; if ( value < 0 ) wait(); }

  50. 4.3 Third Attempt public synchronized void V() { value++; if ( value <= 0 ) notify(); }

More Related