Presentation is loading. Please wait.

Presentation is loading. Please wait.

David Evans CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Concurrent Programming.

Similar presentations


Presentation on theme: "David Evans CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Concurrent Programming."— Presentation transcript:

1 David Evans http://www.cs.virginia.edu/evans CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Concurrent Programming

2 28 October 2003CS 201J Fall 20032 Menu Section Problems Concurrent Programming

3 28 October 2003CS 201J Fall 20033 StringSet <= StringBag ? Signature rule: subtype must implement all supertype methods –StringBag has method public int count (String s) not implemented by StringSet Signature rule is violated: StringSet is not a behavioral subtype of StringBag. Example: The statement s.count (“test”); is possible if s is a StringBag, but not if s is a StringSet.

4 28 October 2003CS 201J Fall 20034 StringSet <= StringBag ? Methods rule: precondition of subtype method must be weaker than precondition of supertype method StringBag: public void insert (String s) // REQUIRES: true StringSet: public void insert (String s) // REQUIRES: s is not an element of this. true  s is not an element of this

5 28 October 2003CS 201J Fall 20035 StringBag <= StringSet Signature Rule –StringBag implements all StringSet methods –Argument types contravariant (all are same), result types covariant (all are same), no new exceptions Methods Rule –Preconditions are weaker insert: s is not an element of this  true

6 28 October 2003CS 201J Fall 20036 StringBag <= StringSet Methods Rule: Postconditions are stronger StringBag () post  StringSet () post StringBag.insert post  StringSet.insert post “Adds s to this” StringBag.isIn post  StringSet.isIn post “Returns true if there is at least one s in this”  “Returns true if s is an element of this” StringBag.size post  StringSet.size post “Returns the total number of elements in this”  “Returns the number of elements in this”

7 28 October 2003CS 201J Fall 20037 StringBag <= StringSet Properties Rule: subtype preserves supertype properties StringSet: // OVERVIEW: StringSets are unbounded, mutable sets of Strings. StringBag: // OVERVIEW: StringBags are unbounded, // mutable bags (unordered, but the same // String may appear multiple times) of // Strings.

8 28 October 2003CS 201J Fall 20038 Programming Concurrency Java API: Thread –A separate execution thread –Methods Thread (Runnable r) Create a thread. The thread’s run method will invokve r.run (). start () REQUIRES: this is not already started Schedule the thread to run. The VM will start the thread and involve run ().

9 28 October 2003CS 201J Fall 20039 Yarn public class Yarn extends Thread { public void run () { System.err.println ("Running thread: " + currentThread ()); } public static void main (String args[]) { Yarn y = new Yarn (); y.start (); System.err.println ("Done: " + currentThread ()); } What could this produce?

10 28 October 2003CS 201J Fall 200310 Yarn public class Yarn extends Thread { public void run () { System.err.println ("Running thread: " + currentThread ()); } public static void main (String args[]) { Yarn y = new Yarn (); y.start (); System.err.println ("Done: " + currentThread ()); } Done: Thread[main,5,main] Running thread: Thread[Thread-0,5,main] Actual output: Running thread: Thread[Thread-0,5,main] Done: Thread[main,5,main] Plausible output:

11 28 October 2003CS 201J Fall 200311 Yarn public class Yarn extends Thread { public void run () { while (true) { System.err.println ("Running thread: " + currentThread ()); } public static void main (String args[]) { Yarn y = new Yarn (); y.start (); System.err.println ("Done: " + currentThread ()); } Done: Thread[main,5,main] Running thread: Thread[Thread-0,5,main]

12 28 October 2003CS 201J Fall 200312 class Counter { private int count; public Counter () { count = 0; } public void increment () { count++; } public void decrement () { count--; } public int getValue () { return count; } } class IncThread extends Thread { private Counter c; public IncThread (Counter p_c) { c = p_c; } public void run () { while (true) { c.increment (); System.err.println ("Running inc thread: " + currentThread () + " / Value: " + c.getValue ()); }

13 28 October 2003CS 201J Fall 200313 class DecThread extends Thread { private Counter c; public DecThread (Counter p_c) { c = p_c; } public void run () { while (true) { c.decrement (); System.err.println ("Running dec thread: " + currentThread () + " / Value: " + c.getValue ()); } public class Yarn { public static void main (String args[]) { Counter c = new Counter (); IncThread ithread = new IncThread (c); DecThread dthread = new DecThread (c); ithread.start (); dthread.start (); }

14 28 October 2003CS 201J Fall 200314 Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running inc thread: Thread[Thread-0,5,main] / Value: 2 Running inc thread: Thread[Thread-0,5,main] / Value: 3 Running inc thread: Thread[Thread-0,5,main] / Value: 4 … Running inc thread: Thread[Thread-0,5,main] / Value: 61 Running inc thread: Thread[Thread-0,5,main] / Value: 62 Running dec thread: Thread[Thread-1,5,main] / Value: 61 Running inc thread: Thread[Thread-0,5,main] / Value: 62 Running dec thread: Thread[Thread-1,5,main] / Value: 61 Running inc thread: Thread[Thread-0,5,main] / Value: 62 Running dec thread: Thread[Thread-1,5,main] / Value: 61 Running dec thread: Thread[Thread-1,5,main] / Value: 60 … Running dec thread: Thread[Thread-1,5,main] / Value: 1 Running dec thread: Thread[Thread-1,5,main] / Value: 0 Running dec thread: Thread[Thread-1,5,main] / Value: -1 Running inc thread: Thread[Thread-0,5,main] / Value: -1 Running inc thread: Thread[Thread-0,5,main] / Value: 0 Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running inc thread: Thread[Thread-0,5,main] / Value: 2 …

15 28 October 2003CS 201J Fall 200315 Any race conditions? class IncThread extends Thread { private Counter c; public IncThread (Counter p_c) { c = p_c; } public void run () { while (true) { c.increment (); System.err.println ("Running inc thread: " + currentThread () + " / Value: " + c.getValue ()); }

16 28 October 2003CS 201J Fall 200316 public void run () { while (true) { synchronized (c) { c.increment (); System.err.println ("Running inc thread: " + currentThread () + " / Value: " + c.getValue ()); } public void run () { synchronized (c) { while (true) { c.increment (); System.err.println ("Running inc thread: " + currentThread () + " / Value: " + c.getValue ()); } Option 1 Option 2 Would hold the lock on c forever!

17 28 October 2003CS 201J Fall 200317 Banking How can we ensure that the counter value never goes negative?

18 28 October 2003CS 201J Fall 200318 Priorities In general, threads with higher priorities will be scheduled preferentially. There are no guarantees Thread void setPriority (int newPriority) // MODIFIES: this // EFFECTS: Changes the priority of this // thread to newPriority.

19 28 October 2003CS 201J Fall 200319 Priorities, Priorities ithread.setPriority (Thread.NORM_PRIORITY); ithread.start (); dthread.setPriority (Thread.MIN_PRIORITY); dthread.start (); The ithread should run more than the dthread, but there is no guarantee.

20 28 October 2003CS 201J Fall 200320 wait and notify Thread A synchronized (o) o.wait () Thread B synchronized (o) { o.notify () } // end synchronized can reclaim o lock

21 28 October 2003CS 201J Fall 200321 public class Object { public final void wait () throws InterruptedException // REQUIRES: Current thread holds the // lock for this. // EFFECTS: Causes the current thread // to release the lock and wait until // notify is called on this. If the thread // is interrupted throws InterruptedException public final void notify () // EFFECTS: If any threads are waiting on this // object, chooses one of those threads to // awaken. final means subtypes may not override this method

22 28 October 2003CS 201J Fall 200322 class IncThread extends Thread { private Counter c; public IncThread (Counter p_c) { c = p_c; } public void run () { while (true) { synchronized (c) { c.increment (); System.err.println ("Running inc thread: " + currentThread () + …); c.notify (); } } } } class DecThread extends Thread { … public void run () { while (true) { synchronized (c) { if (c.getValue () <= 0) { try { c.wait (); } catch (InterruptedException e) { ; } } c.decrement (); System.err.println ("Running dec thread: " + …); } } } }

23 28 October 2003CS 201J Fall 200323 Counter c = new Counter (); IncThread ithread = new IncThread (c); DecThread dthread = new DecThread (c); ithread.setPriority (Thread.NORM_PRIORITY); ithread.start (); dthread.setPriority (Thread.MAX_PRIORITY); dthread.start (); Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running dec thread: Thread[Thread-1,10,main] / Value: 0 Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running dec thread: Thread[Thread-1,10,main] / Value: 0 Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running dec thread: Thread[Thread-1,10,main] / Value: 0 Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running dec thread: Thread[Thread-1,10,main] / Value: 0

24 28 October 2003CS 201J Fall 200324 Charge Thread work = new Thread (ps5); work.setPriority (Thread.MAX_PRIORITY); work.start ();


Download ppt "David Evans CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Concurrent Programming."

Similar presentations


Ads by Google