Presentation is loading. Please wait.

Presentation is loading. Please wait.

Multi-Threaded Programming Design CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L.

Similar presentations


Presentation on theme: "Multi-Threaded Programming Design CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L."— Presentation transcript:

1 Multi-Threaded Programming Design CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

2 Outline USC CSCI 201L2/16 ▪B▪Blocking Queues ▪M▪Multi-Threaded Programming Design

3 Producer/Consumer Problem Review ▪There are two classes – Producer and Consumer ▪In a shared variable (buffer in the following example), the Producer increases the value and the Consumer decreases the value ▪The shared variable has a maximum capacity that the value cannot exceed (CAPACITY in the following example) ›If the Producer tries to add a value when the buffer has reached its capacity, it must wait for the Consumer (with the condition notFull in the following example) ▪The shared variable has a minimum capacity that the value cannot pass (0 in the following example) ›If the Consumer tries to decrease the value when the buffer has reached its minimum capacity, it must wait for the Producer (with the condition notEmpty in the following example) USC CSCI 201L3/16 Blocking Queues

4 Producer/Consumer Example with Monitors 1 import java.util.LinkedList; 2 import java.util.concurrent.ExecutorService; 3 import java.util.concurrent.Executors; 4 5 public class ProducerConsumerWithMonitors { 6 private static Buffer buffer = new Buffer(); 7 8 public static void main(String [] args) { 9 ExecutorService executor = Executors.newFixedThreadPool(2); 10 executor.execute(new ProducerTask()); 11 executor.execute(new ConsumerTask()); 12 executor.shutdown(); 13 } 14 15 private static class ProducerTask implements Runnable { 16 public void run() { 17 try { 18 int i = 1; 19 while (true) { 20 System.out.println("Producer writes: " + i); 21 buffer.write(i++); 22 Thread.sleep((int)(Math.random() * 1000)); 23 } 24 } catch (InterruptedException ie) { 25 System.out.println("Producer IE: " + ie.getMessage()); 26 } 27 } 28 } 29 30 private static class ConsumerTask implements Runnable { 31 public void run() { 32 try { 33 while (true) { 34 System.out.println("\t\tConsumer reads: " + buffer.read()); 35 Thread.sleep((int)(Math.random() * 1000)); 36 } 37 } catch (InterruptedException ie) { 38 System.out.println("Consumer IE: " + ie.getMessage()); 39 } 40 } 41 } USC CSCI 201L4/16 Producer/Consumer 42 private static class Buffer { 43 private static final int CAPACITY = 1; 44 private LinkedList queue = new LinkedList (); 45 private static Object notEmpty = new Object(); 46 private static Object notFull = new Object(); 47 48 public void write(int value) { 49 synchronized(notFull) { 50 synchronized(notEmpty) { 51 try { 52 while (queue.size() == CAPACITY) { 53 System.out.println("Wait for notFull condition " + value); 54 notFull.wait(); 55 } 56 queue.offer(value); 57 notEmpty.notify(); 58 } catch (InterruptedException ie) { 59 System.out.println("Buffer.write IE: " + ie.getMessage()); 60 } 61 } 62 } 63 } 64 65 public int read() { 66 int value = 0; 67 synchronized(notFull) { 68 synchronized(notEmpty) { 69 try { 70 while (queue.isEmpty()) { 71 System.out.println("\t\tWait for notEmpty condition"); 72 notEmpty.wait(); 73 } 74 value = queue.remove(); 75 notFull.notify(); 76 } catch (InterruptedException ie) { 77 System.out.println("Buffer.read IE: " + ie.getMessage()); 78 } 79 } 80 } 81 return value; 82 } 83 } // ends class Buffer 84 } // ends class ProducerConsumerWithMonitors

5 Producer/Consumer Example with Locks/Conditions 1 import java.util.LinkedList; 2 import java.util.concurrent.ExecutorService; 3 import java.util.concurrent.Executors; 4 import java.util.concurrent.locks.Condition; 5 import java.util.concurrent.locks.Lock; 6 import java.util.concurrent.locks.ReentrantLock; 7 8 public class ProducerConsumerWithLocks { 9 private static Buffer buffer = new Buffer(); 10 11 public static void main(String [] args) { 12 ExecutorService executor = Executors.newFixedThreadPool(2); 13 executor.execute(new ProducerTask()); 14 executor.execute(new ConsumerTask()); 15 executor.shutdown(); 16 } 17 18 private static class ProducerTask implements Runnable { 19 public void run() { 20 try { 21 int i = 1; 22 while (true) { 23 System.out.println("Producer tries to write: " + i); 24 buffer.write(i++); 25 Thread.sleep((int)(Math.random() * 1000)); 26 } 27 } catch (InterruptedException ie) { 28 System.out.println("Producer IE: " + ie.getMessage()); 29 } 30 } 31 } 32 33 private static class ConsumerTask implements Runnable { 34 public void run() { 35 try { 36 while (true) { 37 System.out.println("\t\tConsumer reads: " + buffer.read()); 38 Thread.sleep((int)(Math.random() * 1000)); 39 } 40 } catch (InterruptedException ie) { 41 System.out.println("Consumer IE: " + ie.getMessage()); 42 } 43 } 44 } USC CSCI 201L5/16 Producer/Consumer 45 private static class Buffer { 46 private static final int CAPACITY = 1; 47 private LinkedList queue = new LinkedList (); 48 private static Lock lock = new ReentrantLock(); 49 private static Condition notEmpty = lock.newCondition(); 50 private static Condition notFull = lock.newCondition(); 51 52 public void write(int value) { 53 lock.lock(); 54 try { 55 while (queue.size() == CAPACITY) { 56 System.out.println("Wait for notFull condition " + value); 57 notFull.await(); 58 } 59 queue.offer(value); 60 notEmpty.signal(); 61 } catch (InterruptedException ie) { 62 System.out.println("Buffer.write IE: " + ie.getMessage()); 63 } finally { 64 lock.unlock(); 65 } 66 } 67 68 public int read() { 69 int value = 0; 70 lock.lock(); 71 try { 72 while (queue.isEmpty()) { 73 System.out.println("\t\tWait for notEmpty condition"); 74 notEmpty.await(); 75 } 76 value = queue.remove(); 77 notFull.signal(); 78 } catch (InterruptedException ie) { 79 System.out.println("Buffer.read IE: " + ie.getMessage()); 80 } finally { 81 lock.unlock(); 82 return value; 83 } 84 } 85 } // ends class Buffer 86 } // ends class ProducerConsumerWithLocks

6 Producer/Consumer Output USC CSCI 201L6/16 Blocking Queues

7 ▪A blocking queue causes a thread to block (i.e. move to the waiting state) when you try to add an element to a full queue or to remove an element from an empty queue ›It will remain there until the queue is no longer full or no longer empty ›There are three blocking queues in Java: ArrayBlockingQueue, LinkedBlockingQueue, and PriorityBlockingQueue USC CSCI 201L7/16 Blocking Queues

8 Producer/Consumer with Blocking Queues 1 import java.util.concurrent.ArrayBlockingQueue; 2 import java.util.concurrent.ExecutorService; 3 import java.util.concurrent.Executors; 4 5 public class ProducerConsumer { 6 private static ArrayBlockingQueue buffer = new ArrayBlockingQueue (2); 7 8 public static void main(String [] args) { 9 ExecutorService executor = Executors.newFixedThreadPool(2); 10 executor.execute(new ProducerTask()); 11 executor.execute(new ConsumerTask()); 12 executor.shutdown(); 13 } 14 15 private static class ProducerTask implements Runnable { 16 public void run() { 17 try { 18 int i = 1; 19 while (true) { 20 System.out.println("Producer writes: " + i); 21 buffer.put(i++); 22 Thread.sleep((int)(Math.random() * 10000)); 23 } 24 } catch (InterruptedException ie) { 25 System.out.println("Producer IE: " + ie.getMessage()); 26 } 27 } 28 } 29 30 private static class ConsumerTask implements Runnable { 31 public void run() { 32 try { 33 while (true) { 34 System.out.println("\t\t\tConsumer reads: " + buffer.take()); 35 Thread.sleep((int)(Math.random() * 10000)); 36 } 37 } catch (InterruptedException ie) { 38 System.out.println("Consumer IE: " + ie.getMessage()); 39 } 40 } 41 } 42 } USC CSCI 201L8/16 Blocking Queues

9 Outline USC CSCI 201L9/16 ▪B▪Blocking Queues ▪M▪Multi-Threaded Programming Design

10 Avoiding Deadlock ▪Deadlock can occur when two threads are both waiting on locks the other thread has ▪This can be avoided if locks are obtained in the same order every time ›If the lock on object1 is always obtained before the lock on object2, deadlock will be avoided in the above example ›NOTE: If Thread1 waits on object1 inside the object2 synchronization, deadlock can still occur (which is what we did in the ProducerConsumer example with monitors) USC CSCI 201L10/16 Multi-Threaded Programming Design

11 Java Collections Synchronization ▪The classes in the Java Collections framework are not thread-safe ›Vector, Stack, and Hashtable are thread-safe, but they are older objects that have been replaced by ArrayList, LinkedList, and Map ▪There are methods in the Collections class that can be used for obtaining thread-safe versions of any of the Collection objects ›A synchronized collection object has all the methods that access and update the original collection synchronized USC CSCI 201L11/16 Multi-Threaded Programming Design

12 Iterators and Synchronized Collections ▪Even though we can get a synchronized Collection object, the iterator is fail-fast (not synchronized) ›If the collection being iterated over is modified by another thread, the iterator will throw a java.util.ConcurrentModificationException ›We can avoid this by obtaining a lock on the object over which we are iterating before we begin iterating USC CSCI 201L12/16 Multi-Threaded Programming Design

13 Synchronized Collections Example #1 1 import java.util.Collections; 2 import java.util.HashSet; 3 import java.util.Iterator; 4 import java.util.Set; 5 6 public class CollectionsTest { 7 8 public static void main(String [] args) { 9 for (int i=0; i < 100; i++) { 10 MyThread mt = new MyThread(i); 11 mt.start(); 12 } 13 } 14 } 15 16 class MyThread extends Thread { 17 private static Set hashSet = Collections.synchronizedSet(new HashSet ()); 18 private int num; 19 public MyThread(int num) { 20 this.num = num; 21 hashSet.add(num); 22 } 23 public void run() { 24 System.out.print("thread " + num + ": "); 25 Iterator iterator = hashSet.iterator(); 26 while (iterator.hasNext()) { 27 System.out.print(iterator.next() + " "); 28 } 29 System.out.println(); 30 } 31 } USC CSCI 201L13/16 Multi-Threaded Programming Design

14 Synchronized Collections Example #2 1 import java.util.Collections; 2 import java.util.HashSet; 3 import java.util.Iterator; 4 import java.util.Set; 5 import java.util.concurrent.locks.Lock; 6 import java.util.concurrent.locks.ReentrantLock; 7 8 public class CollectionsTest { 9 10 public static void main(String [] args) { 11 for (int i=0; i < 100; i++) { 12 MyThread mt = new MyThread(i); 13 mt.start(); 14 } 15 } 16 } 17 18 class MyThread extends Thread { 19 private static Set hashSet = Collections.synchronizedSet(new HashSet ()); 20 private static Lock lock = new ReentrantLock(); 21 private int num; 22 public MyThread(int num) { 23 this.num = num; 24 hashSet.add(num); 25 } 26 public void run() { 27 lock.lock(); 28 try { 29 System.out.print("thread " + num + ": "); 30 Iterator iterator = hashSet.iterator(); 31 while (iterator.hasNext()) { 32 System.out.print(iterator.next() + " "); 33 } 34 System.out.println(); 35 } finally { 36 lock.unlock(); 37 } 38 } 39 } USC CSCI 201L14/16 Multi-Threaded Programming Design

15 Synchronized Collections Example #3 1 import java.util.Collections; 2 import java.util.HashSet; 3 import java.util.Iterator; 4 import java.util.Set; 5 import java.util.concurrent.locks.Lock; 6 import java.util.concurrent.locks.ReentrantLock; 7 8 public class CollectionsTest { 9 10 public static void main(String [] args) { 11 for (int i=0; i < 100; i++) { 12 MyThread mt = new MyThread(i); 13 mt.start(); 14 } 15 } 16 } 17 18 class MyThread extends Thread { 19 private static Set hashSet = Collections.synchronizedSet(new HashSet ()); 20 private static Lock lock = new ReentrantLock(); 21 private int num; 22 public MyThread(int num) { 23 this.num = num; 24 lock.lock(); 25 try { 26 hashSet.add(num); 27 } finally { 28 lock.unlock(); 29 } 30 } 31 public void run() { 32 lock.lock(); 33 try { 34 System.out.print("thread " + num + ": "); 35 Iterator iterator = hashSet.iterator(); 36 while (iterator.hasNext()) { 37 System.out.print(iterator.next() + " "); 38 } 39 System.out.println(); 40 } finally { 41 lock.unlock(); 42 } 43 } 44 } USC CSCI 201L15/16 Multi-Threaded Programming Design

16 Synchronized Collections Example #4 1 import java.util.Collections; 2 import java.util.HashSet; 3 import java.util.Iterator; 4 import java.util.Set; 5 6 public class CollectionsTest { 7 8 public static void main(String [] args) { 9 for (int i=0; i < 100; i++) { 10 MyThread mt = new MyThread(i); 11 mt.start(); 12 } 13 } 14 } 15 16 class MyThread extends Thread { 17 private static Set hashSet = Collections.synchronizedSet(new HashSet ()); 18 private int num; 19 public MyThread(int num) { 20 this.num = num; 21 hashSet.add(num); 22 } 23 public void run() { 24 synchronized (hashSet) { 25 System.out.print("thread " + num + ": "); 26 Iterator iterator = hashSet.iterator(); 27 while (iterator.hasNext()) { 28 System.out.print(iterator.next() + " "); 29 } 30 System.out.println(); 31 } 32 } 33 } USC CSCI 201L16/16 Multi-Threaded Programming Design


Download ppt "Multi-Threaded Programming Design CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L."

Similar presentations


Ads by Google