Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Thread & concurrancy


Published on

Module 1: Synchronization
Module 2: Explicit Lock
Module 3: Liveness
Module 4: Guarded Blocks
Module 5: High Level Concurrency Objects
Module 6: Concurrent Collection
Module 7: Atomic Variables & Semaphores
Module 8: Monitor & Countdown Latches

Published in: Software
  • Be the first to comment

  • Be the first to like this

Thread & concurrancy

  1. 1. Thread & Concurrency Onkar Deshpande
  2. 2. Topics  Module 1: Synchronization  Module 2: Explicit Lock  Module 3: Liveness  Module 4: Guarded Blocks  Module 5: High Level Concurrency Objects  Module 6: Concurrent Collection  Module 7: Atomic Variables & Semaphores  Module 8: Monitor & Countdown Latches Onkar Deshpande 2
  3. 3. Module 1: Synchronization  Overview  Thread Interference  Memory Consistency Errors  Synchronized Methods  Intrinsic Locks and Synchronization Onkar Deshpande 3
  4. 4. Thread Interference  Threads are lightweight processes and also provide an execution environment  Threads share the process's resources, including memory . This makes for efficient, but potentially problematic, communication.  Interference happens when two operations, running in different threads, but acting on the same data, interleave.  This means that the two operations consist of multiple steps, and the sequences of steps overlap. Onkar Deshpande 4
  5. 5. Memory Consistency Errors  Memory consistency errors occur when different threads have inconsistent views of what should be the same data.  Happens-before relationship between these two statements. eg: int counter = 0; The counter field is shared between two threads, A and B. thread A increments counter:counter++; Then, shortly afterwards, thread B prints out counter: System.out.println(counter);  There are several actions that create happens-before relationships. One of them is synchronization Onkar Deshpande 5
  6. 6. Synchronized Methods  Synchronized methods has two effects:  Only one thread is allowed to access synchronized methods at particular instant.  It automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.  Synchronized methods prevents thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. Onkar Deshpande 6
  7. 7. Intrinsic Locks and Synchronization  A thread needs to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done  When a thread releases an intrinsic lock, a happens- before relationship is established between that action and any subsequent acquisition of the same lock.  Synchronized Block: synchronized(this) { } Onkar Deshpande 7
  8. 8. Atomic Access  Atomic action either happens completely, or it doesn't happen at all.  Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).  Reads and writes are atomic for all variable declared volatile (including long and double variables). Onkar Deshpande 8
  9. 9. Atomic Access  Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.  Simple atomic variable access is more efficient than accessing these variables through synchronized code, Onkar Deshpande 9
  10. 10. Module 2: Explicit Lock  Overview  Intrinsic Lock  It’s Limitations  Reentrant Locks  Reentrant Read Write Lock  Intrinsic v/s Extrinsic  Problems with locking  Lock free and wait free algorithms Onkar Deshpande 10
  11. 11. Intrinsic Locks  Synchronized  Uses intrinsic locks and monitors  Every object has intrinsic lock  Volatile  In Java 5.0 new addition Onkar Deshpande 11
  12. 12. Functional limitations of intrinsic locks  Lock Interruptibly  Try lock  Cannot implement non-block-structured locking disciplines  Fully contained within a single method  When exception is thrown in critical section Onkar Deshpande 12
  13. 13. Reentrant Lock  Enhance intrinsic locking capabilities  Re-entrant Lock also supports :  Polled and Timed Lock Acquisition  Interruptible Lock Acquisition  Non-block Structured Locking  Fairness Onkar Deshpande 13
  14. 14. Re-entrant Read Write Lock  The conditions for getting read and write access to the resource: Read Access Write Access If no threads are writing, and no threads have requested write access. If no threads are reading or writing. Onkar Deshpande 14
  15. 15. Intrinsic v/s Extrinsic  Same mechanism for locking  Performance improvement is purely subjective  Extrinsic locks give a more explicit control mechanism for better handling of deadlocks, starvation, and so on. Onkar Deshpande 15
  16. 16. Problems with locking  Performance degradation  Priority Inversion  Deadlock  Heavy weight stuff Onkar Deshpande 16
  17. 17. Lock-free and wait-free algorithms  Also known as Non-blocking algorithms  Based on CAS  Java.util.concurrent package Onkar Deshpande 17
  18. 18. References locks.html rency/changes8.html Onkar Deshpande 18
  19. 19. Module 3: Liveness  Overview  Deadlock  How to avoid deadlock?  Starvation & Livelock. Onkar Deshpande 19
  20. 20. What is Deadlock?  Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.  Deadlock occurs when multiple threads need the same locks but obtain them in different order.  It can only happen when the program is running multiple threads, and multiple locks are being used by multiple threads.  A single-threaded program will never have deadlocks.  A program with one lock will never have deadlocks. Onkar Deshpande 20
  21. 21. How to avoid deadlock ?  The simplest and most efficient way to avoid deadlock is to ensure that resources are always acquired in some well-defined order.  Another way is to prevent the potential for deadlock by acquiring more than one lock at a time.  Avoid Nested locks.  It’s always best to use thread.join() with maximum time you want to wait for the other thread to finish. Onkar Deshpande 21
  22. 22. Starvation  What is Starvation?  Its causes:  Inappropriate thread priorities.  Synchronize method which takes lot of time to return.  How its different from deadlock?  How to prevent Starvation?  Priority scheme can be used to ensure that starvation does not occur due to a scheduler.  Queuing disciplines (such as FIFO) can guarantee starvation will not occur. Onkar Deshpande 22
  23. 23. Livelock  What is Livelock?  Livelock is a situation in which a non-blocked thread cannot make any progress because it keeps retrying an operation that will always fail.  How its different from deadlock?  Detection is less obvious from simple observation than deadlock due to the fact that the program counter doesn’t freeze.  Livelock results in CPU cycles wastage. Onkar Deshpande 23
  24. 24. Module 4: Guarded Blocks  Overview  Guarded Blocks  Immutable Objects  Creating your own Immutable Objects Onkar Deshpande 24
  25. 25. Guarded Blocks  A Guarded block is a strategy to achieve co-ordination between Threads which attempt to modify shared data  Such blocks are controlled by a condition which determines whether or not the shared data can be modified Onkar Deshpande 25
  26. 26. Guarded Blocks  Real life example where a guarded block could be used  John and Jenny hold a joint account in a Bank, with USD 10000 account balance.  One fine day Jenny deposits USD 1000 by cash to her account.  While her account is updating, her husband John deposits USD 1000 to her account almost at the same time from another branch.  Her balance is now updated to USD 11000 thereby ignoring her last deposit of USD 1000. Basically we lost one update which happened on her account!  This problem has occurred because two transactions are working on the same resource without knowing each other’s activity. Onkar Deshpande 26
  27. 27. Guarded Blocks example public void readBalance() { try { System.out.println(Thread.currentThread().getName() + " " + new Date() + " Current balance " + balance); Thread.sleep(1000); } catch (Exception ex) {ex.printStackTrace();} } public void deposit(float amount) { try { balance += amount; System.out.println(Thread.currentThread().getName() + " " + new Date() + " New balance " + balance); } catch (Exception ex) {ex.printStackTrace();} } Onkar Deshpande 27 Reading the Balance Making the deposit Result Jenny Wed Aug 06 08:43:32 IST 2014 Current balance 10000.0 John Wed Aug 06 08:43:32 IST 2014 Current balance 10000.0 Jenny Wed Aug 06 08:43:33 IST 2014 New balance 11000.0 John Wed Aug 06 08:43:33 IST 2014 New balance 11000.0
  28. 28. Example boolean accountReady = true; //This method will be called before deposit is made public synchronized void verify() { while (!accountReady) { try { System.out.println(Thread.currentThread().getName() + " " + new Date() + " Waiting for account to be ready"); wait(); } catch (InterruptedException ex) {ex.printStackTrace();}} System.out.println(Thread.currentThread().getName() + " " + new Date() + " Account is now ready"); } //This method will be called after deposit is made public synchronized void readyAccount() { accountReady = true; notifyAll(); } Onkar Deshpande 28 Guarding condition
  29. 29. Guarded Blocks example public void deposit(float amount) { try { verify(); accountReady = false; Thread.sleep(2000); balance += amount; System.out.println(Thread.currentThread(). getName() + " "+ new Date() + " New balance " + balance); } catch (Exception ex) { ex.printStackTrace(); } readyAccount(); } Onkar Deshpande 29 Output Jenny Wed Aug 06 09:18:21 IST 2014 Current balance 10000.0 John Wed Aug 06 09:18:21 IST 2014 Current balance 10000.0 Jenny Wed Aug 06 09:18:22 IST 2014 Account is now ready John Wed Aug 06 09:18:22 IST 2014 Waiting for account to be ready Jenny Wed Aug 06 09:18:24 IST 2014 New balance 11000.0 John Wed Aug 06 09:18:24 IST 2014 Account is now ready John Wed Aug 06 09:18:26 IST 2014 New balance 12000.0 Making the deposit
  30. 30. Immutable Objects  An object is considered immutable if its state cannot change after it is constructed.  If we try to modify the immutable object ,will get the another immutable object as result. String class is an example of immutable object.  Immutable objects are by default thread-safe, can be shared without synchronization in concurrent environment. Onkar Deshpande 30
  31. 31. Creating your own Immutable Objects  Set the values of properties using constructor only, Avoid setters for fields.  Create a final class . Make all fields final and private.  If the instance fields include references to mutable objects, don't allow those objects to be changed:  Don't provide methods that modify the mutable objects.  Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods. Onkar Deshpande 31
  32. 32. Module 5: High Level Concurrency Objects  Overview  Lock Objects  Threads pools with the Executor Framework  Thread Pools  Executor Framework  Executers Interfaces  Benefits  Fork & Join 32Onkar Deshpande 32
  33. 33. Lock Objects  Synchronized Blocks and Monitors with java.lang.Thread class are adequate for very basic tasks, but higher-level building blocks are needed for more advanced tasks.  High-level concurrency features are introduced with java 5.0 Most of these features are implemented in the new java.util.concurrent  Lock implementations provide more extensive locking operations compared to Synchronized methods and blocks. Onkar Deshpande 33
  34. 34. Interface Lock (java.util.concurrent.Locks): Method Summary Modifier and Type Method and Description void lock() Acquires the lock. void lockInterruptibly() Acquires the lock unless the current thread is interrupted. Condition newCondition() Returns a new Condition instance that is bound to this Lock instance. boolean tryLock() Acquires the lock only if it is free at the time of invocation. boolean tryLock(long time, TimeUnit unit) Acquires the lock if it is free within the given waiting time and the current thread has not been interrupted. void unlock() Releases the lock. Onkar Deshpande 34
  35. 35. Case of Deadlock import; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockDemo { static Lock lock = new ReentrantLock(); void f () throws Exception { lock.lock(); FileInputStream f = new FileInputStream("file.txt"); // Do something with file f.close(); lock.unlock(); } } Lock not released if exception thrown Likely to cause deadlock some time later Onkar Deshpande 35
  36. 36. Solution: Use Finally import; import java.util.concurrent.locks.*; public class LockDemo { static Lock lock = new ReentrantLock(); void f() throws Exception { lock.lock(); try { FileInputStream f = new FileInputStream("file.txt"); // Do something with f f.close(); } finally { // This code executed no matter how we exit the try block lock.unlock(); } } } Onkar Deshpande 36
  37. 37. Threads pools with the Executor Framework  Executors framework  Released with the JDK 5  For large-scale applications, it makes sense to separate thread management and creation from the rest of the application.  Objects that encapsulate these functions are known as Executors.  Used to run the Runnable objects without creating new threads every time and mostly re-using the already created threads. Onkar Deshpande 37
  38. 38. Thread pool  Collection of Runnable objects (work queue) & connections of running threads (worker threads).  Pool of worker threads, which is ready to perform any task.  These threads are constantly running and are checking the work queue for new work. If there is new work to be done they execute this Runnable.  Core of this thread pool framework is Executor interface which defines abstraction of task execution with method execute(Runnable task) and ExecutorService which extends Executor to add various life-cycle and thread pool management facilities like shutting down thread pool. Onkar Deshpande 38
  39. 39. Executor Interfaces  The java.util.concurrent package defines three executor interfaces:  The Executor Interface: provides a single method, execute(). If r is a Runnable object, and e is an Executor object you can replace  (new Thread(r)).start() with e.execute(r)  The ExecutorService Interface: provides submit method and other thread life cycle methods.  submit(Callable <T> task)  submit(Runnable task)  submit(Runnable task, T result)  void shutdown()  boolean isShutdown()  The ScheduledExecutorService Interface: provides methods of it’s parent ExecutorService with Schedule. Onkar Deshpande 39
  40. 40. Implementing Thread Pool  One common type of thread pool is the fixed thread pool. Below are related classes.  java.util.concurrent.Executors  The newCachedThreadPool method creates an executor with an expandable thread pool. This executor is suitable for applications that launch many short- lived tasks.  The newSingleThreadExecutor method creates an executor that executes a single task at a time.  Several factory methods are ScheduledExecutorService versions of the above executors.  java.util.concurrent.ThreadPoolExecutor  We can specify the number of threads that will be alive when we create ThreadPoolExecutor instance and we can limit the size of thread pool and create our own RejectedExecutionHandler implementation to handle the jobs that can’t fit in the worker queue.  java.util.concurrent.ScheduledThreadPoolExecutor  An ExecutorService which can schedule tasks to run after a delay, or to execute repeatedly with a fixed interval of time in between each execution. Onkar Deshpande 40
  41. 41. Fork/Join Framework  Fork/Join framework  Released with the JDK 7  Distribute the work across multiple cores and then join them to return the result set  Fork-Join breaks the task at hand into mini-tasks.  No worker thread is idle.  Implement a work-stealing algorithm(Unlike the Executor framework) Onkar Deshpande 41
  42. 42. Fork/Join Framework Onkar Deshpande 42
  43. 43. Example of Fork/Join Pool Framework  A program that will search for files with a determined extension inside a folder and its subfolders  The ForkJoinTask class will process the content of a folder.  For each subfolder inside that folder, it will send a new task to the ForkJoinPool class in an asynchronous way. Onkar Deshpande 43
  44. 44. Existing Implementations in JDK  java.util.Arrays class for its parallelSort() methods in JDK 8.  Parallel sorting of large arrays is faster than sequential sorting when run on multiprocessor systems. Onkar Deshpande 44
  45. 45. References cle.html executor-framework-tutorial-and-best-practices/ create-thread-pools-in-java-executors- framework-example-tutorial.html Onkar Deshpande 45
  46. 46. Module 6: Concurrent Collection  Overview  What are Concurrent Collections?  Need of Concurrent Collections  Concurrent Collection Classes  Example Onkar Deshpande 46
  47. 47. What are Concurrent Collections?  Introduced in Java 1.5  Java Collections reside inside java.util package where as Concurrent Collections reside inside java.util.concurrent package  Designed for concurrent access from multiple threads  Purpose of these classes is to provide high- performance, highly scalable, thread-safe versions of the basic collection types. Onkar Deshpande 47
  48. 48. Need of Concurrent Collections  In Synchronized Collections, every method is synchronized on a common lock, restricting access to a single thread at a time.  Concurrent Collections uses a finer-grained locking mechanism called lock striping. Onkar Deshpande 48
  49. 49. Concurrent Collections Classes  CopyOnWriteArrayList  ConcurrentMap/ConcurrentHashMap  ConcurrentNavigableMap  ConcurrentLinkedQueue/Deque  Synchronous Queue  Blocking Queue  Blocking Deque  Transfer Queue Onkar Deshpande 49
  50. 50. Example public static void main(String[] args){ List list = new ArrayList(); list.add("A"); Iterator i =list.iterator(); while(i.hasNext()){ System.out.println(; list.add("B"); // throws ConcurrentModificationException } System.out.println("After modification:"); Iterator i2 =list.iterator(); while(i2.hasNext()){ System.out.println(; i2.remove(); // No UnsupportedOperationException is thrown } } Onkar Deshpande 50
  51. 51. Example public static void main(String[] args){ CopyOnWriteArrayList list = new CopyOnWriteArrayList(); list.add("A"); Iterator i =list.iterator(); while(i.hasNext()){ System.out.println(; list.add("B"); // No ConcurrentModificationException is thrown } System.out.println("After modification:"); Iterator i2 =list.iterator(); while(i2.hasNext()){ System.out.println(; i2.remove(); // throws UnsupportedOperationException } } Onkar Deshpande 51
  52. 52. Synchronous Queue  It is a special kind of queue where producer waits until the consumer is ready and consumer waits until the producer is ready.  It can contain only a single element internally.  When you call put() method on Synchronous Queue it blocks until another thread is there to take that element out of the Queue.  Similarly, if a thread tries to remove an element and no element is currently present, that thread is blocked until another thread puts an element into the queue. Onkar Deshpande 52 Put Thread Take Thread Synchronous Queue
  53. 53. Example Thread producer = new Thread("PRODUCER") { public void run() { String event = "FOOD"; try { queue.put(event); // thread will block here System.out.printf("[%s] published event : %s %n", Thread .currentThread().getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; producer.start(); // starting publisher thread Onkar Deshpande 53
  54. 54. Example Thread consumer = new Thread("CONSUMER") { public void run() { try { String event = queue.take(); // thread will block here System.out.printf("[%s] consumed event : %s %n", Thread .currentThread().getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; consumer.start(); // starting consumer thread Onkar Deshpande 54 Output: [PRODUCER] published event : FOOD [CONSUMER] consumed event : FOOD
  55. 55. Things to remember about Synchronous Queue  SynchronousQueue is used to implement queuing strategy of direct hand-off, where thread hands-off to waiting thread.  This queue does not permit null elements, adding null elements will result in NullPointerException.  SynchronousQueue has zero capacity.  You cannot peek at a SynchronousQueue because an element is only present when you try to take it.  You cannot iterate over SynchronousQueue as there is nothing to iterate.  Constructed with fairness policy set to true grants threads access in FIFO order. Onkar Deshpande 55
  56. 56. BlockingQueue  Blocking queue means the Operation on the queue block when the Queue is empty or full.  Happen Before relationship  Producer consumer design pattern implementations.  extends Iterable, Collection and Queue interfaces.  If capacity not decided default is Integer.MAX_VALUE.  Does not accept null values Onkar Deshpande 56
  57. 57. Producer consumer Design pattern Producer Consumer Onkar Deshpande 57
  58. 58. BlockingQueue Implementation  ArrayBlockingQueue  Backed by Array.  Store data in insertion order.  Faster then other BlockingQueue Implementation. Onkar Deshpande 58
  59. 59. BlockingQueue Implementation  LinkedBlockingQueue  Backed by Linked Node  Store data on insertion order  Slower then other BlockingQueue Implementation. Onkar Deshpande 59
  60. 60. BlockingQueue Implementation  PriorityBlockingQueue  Backed by Array  Store data on the Priority (By Default natural order)  Need to implement the Comparable interface. Onkar Deshpande 60
  61. 61. BlockingDeque  Extends the properties of BlockingQueue and Deque.  Retrieval and deletion possible from both ends. Onkar Deshpande 61
  62. 62. TransferQueue ?  It extends BlockingQueue.  It is a refinement of the BlockingQueue interface in which producers can wait for consumers to receive elements.  TransferQueue is useful in scenario where message passing need to be guaranteed.  The main method of TransferQueue is transfer(E e) . Onkar Deshpande 62
  63. 63. Transfer(E e) method in TransferQueue  If, there is an consumers waiting to take element, then producer directly transfers the element to consumer.  If there is no consumer waiting, then producer will not directly put the element and returned, but it will wait for any consumer to consume the element. Onkar Deshpande 63 Producer Consumer TranferQueue Transferring element
  64. 64. TranferQueue v/s BlockingQueue  BlockingQueue: can only put element into queue (and block if queue is full).  TransferQueue: can also block until other thread receives your element (using new transfer method for that). Onkar Deshpande 64
  65. 65. TransferQueue Implementation  LinkedTransferQueue  Backed by Linked Node  Unbounded TransferQueue (no size restriction).  Follows first-in-first-out (FIFO) concept to get and add  Element. Onkar Deshpande 65
  66. 66. TransferQueue Implementation  Some methods of LinkedTransferQueue.  transfer(E e) : Inherited from TransferQueue in which producer transfers the element to consumer and waits if necessary.  put(E e) : producers put the element and it does not throw exception because there is no size restriction.  take() : It retrieves the element from queue and wait if empty. Onkar Deshpande 66
  67. 67. Example static LinkedTransferQueue<String> lnkTransQueue = new LinkedTransferQueue<String>(); public static void main(String[] args) { ExecutorService exService = Executors.newFixedThreadPool(2); Producer producer = new LinkedTransferQueueExample().new Producer(); Consumer consumer = new LinkedTransferQueueExample().new Consumer(); exService.execute(producer); exService.execute(consumer); exService.shutdown(); // Cancel currently executing tasks } Onkar Deshpande 67
  68. 68. Example class Producer implements Runnable { @Override public void run() { for (int i = 0; i < 3; i++) { try { System.out.println("Producer is waiting to transfer..."); lnkTransQueue.transfer("A" + i); System.out.println("producer transfered element: A" + i); } catch (InterruptedException e) { e.printStackTrace(); } } } } Onkar Deshpande 68
  69. 69. Example class Consumer implements Runnable { @Override public void run() { for (int i = 0; i < 3; i++) { try { System.out.println("Consumer is waiting to take element..."); String s = lnkTransQueue.take(); System.out.println("Consumer received Element: " + s); } catch (InterruptedException e) { e.printStackTrace(); } } } } Onkar Deshpande 69
  70. 70. Output Output: Producer is waiting to transfer... Consumer is waiting to take element... Consumer received Element: A0 Consumer is waiting to take element... producer transfered element: A0 Producer is waiting to transfer... producer transfered element: A1 Producer is waiting to transfer... Consumer received Element: A1 Consumer is waiting to take element... Consumer received Element: A2 producer transfered element: A2 Onkar Deshpande 70
  71. 71. Module 7: Atomic Variables & Semaphores  Overview  Presentation on Atomic Variables  Concurrent Random Numbers  Semaphores & Permits 71Onkar Deshpande 71
  72. 72. Atomic Numbers  What are Atomic variables?  What’s wrong with traditional approach.  Necessity of atomic variables.  Example Onkar Deshpande 72
  73. 73. Example public void increment() { boolean valueChanged = false; while(!valueChanged) { int currentVal = count.get(); int nextVal = currentVal + 1; if(count.compareAndSet(currentVal,nextVal)) { valueChanged = true; } } } //Non-blocking CAS approach Onkar Deshpande 73
  74. 74. Concurrent Random Numbers Onkar Deshpande 74 GLOBAL RANDOM GENERATOR Math.random() T1 T2 T3 T4 Random Number Generator T2 Random Number Generator T2
  75. 75. Math.random() v/s ThreadLocalRandom  Random Number Generator  Overheads / Performance  Use Case scenario  When Used ThreadLocalRandom.current().nextDouble();  Time required to calculate Random number by t1 :: 379  Time required to calculate Random number by t2 :: 401  Time required to calculate Random number by t3 :: 400  When Used Math.random();  Time required to calculate Random number by t1 :: 430  Time required to calculate Random number by t2 :: 464  Time required to calculate Random number by t3 :: 576 Onkar Deshpande 75
  76. 76. Semaphore & Permits  What is Semaphore:  A semaphore is a variable or abstract data type that is used for controlling access, by multiple processes, to a common resource in a parallel programming or a multi user environment.  A useful way to think of a semaphore is as a record of how many units of a particular resource are available, coupled with operations to safely adjust that record as units are required or become free, and, if necessary, wait until a unit of the resource becomes available.  Example: Library Analogy  Key Points :  Not releasing after acquire (either missing release call or an exception is thrown and there is no finally block)  Long held semaphores, causing thread starvation  Deadlocks Onkar Deshpande 76
  77. 77. Semaphore and Permits  Permits: Availability count of resource is permit.  It is an integer count set while initializing Semaphore. Onkar Deshpande 77
  78. 78. Reference  concurrency-tutorial-semaphores.html  java/semaphore.html  rrent/ThreadLocalRandom.html  programs-using-atomic-variables/  concurrency-atomic-variables.html Onkar Deshpande 78
  79. 79. Module 8: Monitor & Countdown Latches  Overview  Monitors  Monitors with Locks  Countdown Latches Onkar Deshpande 79
  80. 80. Monitors  Monitors are an other mechanism of concurrent programming.  It's a higher level mechanism than semaphores and also more powerful Onkar Deshpande 80
  81. 81. Monitors  A monitor is concurrency control construct used for synchronization and scheduling  It allows thread to have mutual exclusion  And the ability to wait (block) for certain condition to become true  It also allows notifying other threads that their condition have been met.  Note : All objects in java can be used as built-in monitor objects. Onkar Deshpande 81
  82. 82. Java built-in Wait and Notification Onkar Deshpande 82
  83. 83. Flow of Execution (Example)  SETTING DATA :  Obtain Lock  If full then wait till it is empty  Else set data and signal those threads who were waiting for data to be set  GETTING DATA  Obtain Lock  If empty then wait till it is full  Else get data and signal those threads who were waiting for data to be set Onkar Deshpande 83
  84. 84. Locks and Condition - Example private volatile boolean usedData = true;//mutex for data private final Lock lock = new ReentrantLock(); private final Condition isEmpty = lock.newCondition(); private final Condition isFull = lock.newCondition(); public void setData(int data) throws InterruptedException { lock.lock(); try { while(!usedData) {//wait for data to be used isEmpty.await(); } = data; isFull.signal();//broadcast that the data is now full. usedData = false;//tell others I created new data. }finally { lock.unlock();//interrupt or not, release lock } } Onkar Deshpande 84
  85. 85. Locks and Condition - Example public void getData() throws InterruptedException{ lock.lock(); try { while(usedData) {//usedData is lingo for empty isFull.await(); } isEmpty.signal();//tell the producers to produce some more. usedData = true;//tell others I have used the data. }finally {//interrupted or not, always release lock lock.unlock(); } } Onkar Deshpande 85
  86. 86. What is a CountDown Latch ?  A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads complete.  CountDownLatch was introduced with JDK 1.5 along with other concurrent utilities like CyclicBarrier, Semaphore, Councurrent HashMap and BlockingQueue in java.util.concurrent package. Onkar Deshpande 86
  87. 87. How it works ?  CountDownLatch works by having a counter initialized with number of threads, which is decremented each time a thread complete its execution.  When count reaches to zero, it means all threads have completed their execution, and thread waiting on latch resume the execution. Onkar Deshpande 87
  88. 88. Sample Code public class CountDownLatchDemo { public static void main(String args[]) { final CountDownLatch latch = new CountDownLatch(3); Thread cacheService = new Thread(new Service("CacheService", 1000, latch)); Thread alertService = new Thread(new Service("AlertService", 1000, latch)); Thread validationService = new Thread(new Service("ValidationService", 1000, latch)); cacheService.start(); //separate thread will initialize CacheService alertService.start(); //another thread for AlertService initialization validationService.start(); try{ latch.await(); //main thread is waiting on CountDownLatch to finish System.out.println("All services are up, Application is starting now"); }catch(InterruptedException ie){ ie.printStackTrace(); } } } Onkar Deshpande 88
  89. 89. Sample Code public class Service implements Runnable { private final String name; private final int timeToStart; private final CountDownLatch latch; public Service(String name, int timeToStart, CountDownLatch latch) { = name; this.timeToStart = timeToStart; this.latch = latch; } @Override public void run() { try { Thread.sleep(timeToStart); } catch (InterruptedException ex) { System.out.println("Error in execution :: "+ Service.class.getName()); } System.out.println(name + " is Up"); latch.countDown(); // reduce count of CountDownLatch by 1 } } Onkar Deshpande 89
  90. 90. Use Cases  Achieving Maximum Parallelism : Sometimes we want to start a number of threads at the same time to achieve maximum parallelism.  Wait N threads to completes before start execution : Any server side core Java application which uses services architecture, where multiple services is provided by multiple threads and application can not start processing until all services have started successfully.  Deadlock detection : A very handy use case in which you can use N threads to access a shared resource with different number of threads in each test phase, and try to create a deadlock. Onkar Deshpande 90
  91. 91. Thank You Onkar Deshpande 91