You are on page 1of 27

Cooperative Concurrent Threads

Producer-Consumer Problem Bounded-Buffer Problem (Clients and Servers : Resource Sharing)

cs480 (Prasad)

L11Threads

Simplistic 1-Cell Buffer


class Buffer { Object x; // synchronized public void put (Object _x, String id) { System.out.println( "Done << " + id + " puts " + _x); x = _x; } // synchronized public Object get (String id) { System.out.println( "Done >> " + id + " gets " + x); return x; } }
cs480 (Prasad) L11Threads 2

class Producer extends Thread { private Random r = new Random(); Buffer b; String id; public Producer(Buffer _b, String _id) { b = _b; id = _id; } public void run () { int delay; Integer ir;
try {

while (true) { delay = Math.abs(r.nextInt() % 1999) + 50; sleep(delay); ir = new Integer(delay);


System.out.println("Ready << "+id+" puts "+ ir);

b.put(ir, id);
} }catch } }
cs480 (Prasad) L11Threads 3 (Exception e){System.out.println("Exception$ " + e);};

class Consumer extends Thread { private Random r = new Random(); Buffer b; String id; public Consumer(Buffer _b, String _id) { b = _b; id = _id; } public void run () { int delay; Integer ir = null; try { while (true) { delay = Math.abs(r.nextInt() % 1999) + 50; sleep(delay);
System.out.println("Ready >> " + id + " gets ");

ir = (Integer) } } } }
cs480 (Prasad)

b.get(id);

catch (Exception e) {System.out.println("Exception$ " + e);};

L11Threads

Producer-Consumer : Bounded Buffer


public class PCB { public static void main(String[] args) { Buffer b = new Buffer(); new Consumer(b,"C1") . start(); new Producer(b,"P1") . start(); try {Thread.sleep(1000); } catch (Exception e){}; new Consumer(b,"C2") . start(); new Producer(b,"P2") . start(); } }
cs480 (Prasad) L11Threads 5

Unfettered Run
Ready >> C1 gets Ready << P2 puts 493 Done >> C1 gets null Done << P2 puts 493 Ready << P1 puts 1591 Done << P1 puts 1591 Ready << P1 puts 488 Done << P1 puts 488 Ready >> C2 gets Done >> C2 gets 488 Ready >> C1 gets Done >> C1 gets 488 Ready >> C2 gets Done >> C2 gets 488 Ready << P1 puts 745 Done << P1 puts 745 ...
cs480 (Prasad)

premature (transient stability?!)


... Ready << P2 puts 815 Done << P2 puts 815 Ready >> C2 gets Done >> C2 gets 815 Ready << P1 puts 1223 Done << P1 puts 1223 Ready >> C1 gets Done >> C1 gets 1223 Ready << P2 puts 403 Done << P2 puts 403 Ready >> C2 gets Done >> C2 gets 403 ...

puts

gets

L11Threads

Concurrency control : class Buffer


class Buffer { Object x; boolean empty = true; public synchronized void put (Object _x, String id) throws Exception { ...} public synchronized Object get (String id) throws Exception { ... } }

Two producers (consumers) cannot put(get) two items in (from) the same buffer slot simultaneously. Two producers (consumers) cannot put(get) two items in (from) the same buffer slot without an intervening consumer (producer). A consumer (producer) is not permitted to get (put) an item from (into) buffer if empty (full).
L11Threads 7

cs480 (Prasad)

public synchronized void put (Object _x, String id) throws Exception

while (!empty) empty = ! empty;

wait();
<< "+id+" puts "+ _x);

System.out.println("Done

x = _x; notifyAll(); }

Note that if-then cannot replace while because notifyAll, due to a consumer, can wake up two waiting producers, and only one producer will find the buffer empty. ( race condition )
L11Threads 8

cs480 (Prasad)

public synchronized Object get (String id) throws Exception

while (empty) wait(); empty = ! empty;


System.out.println("Done >> "+id+" gets "+x);

notifyAll(); return x; }

Note that notify cannot always be used in place of notifyAll because a consumer may be woken up. while required because notifyAll due to a producer does not guarantee that wait-ing consumers will find an item in the buffer.
L11Threads 9

cs480 (Prasad)

Synchonization and Mutual Exclusion


Ready >> C2 gets Ready >> C1 gets Ready << P1 puts 1672 Done << P1 puts 1672 Done >> C2 gets 1672 Ready << P2 puts 774 Done << P2 puts 774 Done >> C1 gets 774 Ready << P1 puts 168 Done << P1 puts 168 Ready >> C1 gets Done >> C1 gets 168 Ready << P2 puts 1263 Done << P2 puts 1263 Ready >> C1 gets Done >> C1 gets 1263
cs480 (Prasad) L11Threads

... Ready << P1 puts 622 Done << P1 puts 622 Ready >> C1 gets Done >> C1 gets 622 Ready >> C2 gets Ready << P2 puts 1447 Done << P2 puts 1447 Done >> C2 gets 1447 Ready << P2 puts 96 Done << P2 puts 96 Ready << P2 puts 95 Ready >> C1 gets Done >> C1 gets 96 Done << P2 puts 95 ...

10

Methods in class

Object

public final void wait() throws InterruptedException {...}

Current thread is suspended (after atomically releasing the lock on this) until some other thread invokes notify() or notifyAll() or interrupts. public final void notify() {...} Notifies exactly one thread waiting on this object for a condition to change. The awakened thread cannot proceed until this thread relinquishes the lock. public final void notifyAll() {...} These methods must be invoked inside synchronized code or else IllegalMonitorStateException will be thrown.

cs480 (Prasad)

L11Threads

11

Single Cell Buffer in C#


using System; using System.Threading; class Buffer { Object x; bool empty = true; public void put (Object _x, string id) { lock(this){ while (!empty) Monitor.Wait(this); empty = ! empty; Console.WriteLine("Done << " + id + " puts " + _x); x = _x; Monitor.PulseAll(this); } } public Object get (string id) { lock(this){ while (empty) Monitor.Wait(this); empty = ! empty; Console.WriteLine("Done >> " + id + " gets " + x); Monitor.PulseAll(this); return x; } } } cs480 (Prasad) L11Threads 12

class Producer { private System.Random r = new System.Random(); Buffer b; String id; id = _id; public Producer(Buffer _b, String _id) { b = _b; } public void run () { int delay; try { while (true) { delay = r.Next(2000) + 50; Thread.Sleep(delay); Console.WriteLine("Ready << " + id + " puts " + delay); b.put(delay, id); } } } } cs480 (Prasad) L11Threads 13 catch (Exception e){Console.WriteLine("Exception$ " + e);};

class Consumer { private System.Random r = new System.Random(); Buffer b; String id; id = _id; public Consumer(Buffer _b, String _id) { b = _b; } public void run () { int delay; try { while (true) { delay = r.Next(2000) + 50; Thread.Sleep(delay); Console.WriteLine("Ready >> " + id + " gets "); delay = (int) } } catch (Exception e) {Console.WriteLine("Exception$ " + e);}; } } cs480 (Prasad) L11Threads 14 b.get(id);

public class PCB { public static void Main(string[] args) { Buffer b = new Buffer();
new Thread( new ThreadStart(new Consumer(b,"C1").run)) . Start(); new Thread( new ThreadStart(new Producer(b,"P1").run)) . Start(); try {Thread.Sleep(1000);} catch (Exception e){Console.WriteLine("Exception$ " + e);}; new Thread( new ThreadStart(new Consumer(b,"C2").run)) . Start(); new Thread( new ThreadStart(new Producer(b,"P2").run)) . Start();

} }

cs480 (Prasad)

L11Threads

15

Scripting vs Systems Programming Languages


Designed for gluing applications : flexibility Interpreted Dynamic variable creation Data and code integrated : meta-programming supported Dynamic typing (typeless) Examples: PERL, Tcl, Python, Ruby, Scheme, Visual Basic, etc
LSysVsScipt

Designed for building applications : efficiency Compiled Variable declaration Data and code separated : cannot create/run code on the fly Static typing Examples: PL/1, Ada, Java, C/C++, C#, etc

cs480 (Prasad)

16

(cont d)
Does application implement complex algorithms and data structures? Does application process large data sets (>10,000 items)? Are application functions well-defined, fixed? If yes, consider a system programming language.

Is the main task to connect components, legacy apps? Does the application manipulate a variety of things? Does the application have a GUI? Are the application's functions evolving rapidly? Must the application be extensible? Does the application do a lot of string manipulation? If yes, consider a scripting language.

cs480 (Prasad) LSysVsScipt 17

Current Trends

Hybrid Languages : Scripting + Systems Programming


Recent JVM-based Scripting Languages

Jython : Python dialect Clojure : LISP dialect Scala : OOP +Functional Hybrid

cs480 (Prasad)

LSysVsScipt

18

Jython (for convenient access to Java APIs)


I:\tkprasad\cs480>jython Jython 2.1 on java1.4.1_02 (JIT: null) Type "copyright", "credits" or "license" for more information. >>> import javax.swing as swing >>> win = swing.JFrame("Welcome to Jython") >>> win.size = (200, 200) >>> win.show() >>> ^Z

cs480 (Prasad)

LSysVsScipt

19

Java vs Jython
map = new HashMap(); map.put("one",new Integer(1)); map.put("two",new Integer(2)); map.put("three",new Integer(3));

map = {"one":1,"two":2,"three": 3}

System.out.println(map.get("one"));

print map ["one"]

list = new LinkedList(); list.add(new Integer(1)); list.add(new Integer(2)); list.add(new Integer(3));

list = [1, 2, 3]

cs480 (Prasad)

LSysVsScipt

20

(cont d)
for (Iterator i; i.hasNext();) { i.next(); } List newList = ArrayList() for (Iterator i; i.hasNext();) { Object obj = i.next(); newList.add(function(obj)) } for i in list: (* iterator *)

newList = [function(i) for i in oldList] (* list comprehension *)

cs480 (Prasad)

LSysVsScipt

21

Defining functions and expressions in Jython (file: eg.py)


def fac(x) : factorial function if x <= 1: return 1 return long(x)*fac(x-1) fac(5) # 120L print fac(5), fac(20) print fac.__doc__ #factorial function X = 2 + 3j x.imag + x.conjugate() # (5 3j) list = [pow(i,i) for i in [1,2]] from math import * print PI=%f, e=%f % (pi,e) Y = range(1,9,1) # [1,2,3,4,5,6,7,8] Y[1:3] #[2, 3] Y[::2] #[1, 3, 5, 7]

cs480 (Prasad)

LSysVsScipt

22

More Jython code examples


Dynamic code evaluation print eval ( [1,3] + range(6,10,3) ) # [1, ,3, 6, 9] x = 2 + 3j exec x = 5, x + x #(5, (4+6j)

cs480 (Prasad)

LSysVsScipt

23

Cont d
Exceptions def readfile (name): return lines in file or None if unreadable try: file = open(name, r ) try: # raise IOError return file.readlines() finally: file.close() except IOError, ioe: print Exception , ioe
cs480 (Prasad) LSysVsScipt 24

Cont d
Functional Programming apply(lambda x,y : x*y, (10, 20)) # 200 map(lambda x,y: x + y, [[1,2],[ a ]], [[ 3 ],[ b ]]) # [[1, 2, 3 ], [ a , b ]] reduce(lambda x,y: x + y, [1,2,3], 100) # 106 filter(lambda x: x > 0, range(10,-5,-3)) # [10, 7 , 4, 1]

cs480 (Prasad)

LSysVsScipt

25

Java functionality through Jython


import java.lang as lang import javax.swing as swing import java.awt as awt names = ["Groucho", "Chico", "Harpo"] quotes = {"Groucho": "Say the secret word", "Chico": "Viaduct?", "Harpo": "HONK!"} def buttonPressed(event): field.text = quotes[event.source.text] def exit(event): lang.System.exit(0) def createButton(name): return swing.JButton(name, preferredSize=(100,20), actionPerformed=buttonPressed)
cs480 (Prasad) LSysVsScipt 26

win = swing.JFrame("Welcome to Jython", size=(200, 200),windowClosing=exit) win.contentPane.layout = awt.FlowLayout( ) field = swing.JTextField(preferredSize=(200,20)) win.contentPane.add(field) buttons = [createButton(each) for each in names] for eachButton in buttons: win.contentPane.add(eachButton) win.pack( ) win.show( )

cs480 (Prasad)

LSysVsScipt

27

You might also like