Alternate Rendition in Java
class Echo implements Runnable { public void run() { try { while (true) { [Link](1000); [Link]( ABC ); } } catch (InterruptedException e) { return; } } public static void main (String[] args) { Runnable r = new Echo(); new Thread(r) . start(); } }
cs480 (Prasad)
L11Threads
Threads and Applets
A Simple Bouncing Ball Animation
cs480 (Prasad)
L11Threads
class Ball { static final int TOP = 10, BOTTOM = 150; int incr = 2; int ypos = TOP; void paint([Link] g) { if (ypos < TOP || ypos > BOTTOM) incr= -incr; ypos += incr; [Link]([Link]); [Link](10,ypos, 10,10); }}
cs480 (Prasad)
L11Threads
//
<applet code=[Link] height=200 width=50></applet>
public class Bounce extends [Link] { Ball b; public void init() { b = new Ball(); setBackground([Link]); } public void paint([Link] g) { [Link](g); repaint(15); /* try { while (true) {
[Link](15); repaint(); } catch (InterruptedException e) {}; */
}
cs480 (Prasad)
L11Threads
Threaded Applet
public class ThreadedBounce extends [Link] implements Runnable {
Ball b; Thread t; public void init() { b = new Ball(); setBackground([Link]); t = new Thread(this); [Link](); } ...
cs480 (Prasad) L11Threads 5
... public void paint([Link] g) { [Link](g); // moved the code from here } public void run() { try { while (true) { [Link](15); repaint(); } } catch (InterruptedException e) {}; } }
cs480 (Prasad) L11Threads 6
Another version of Threaded Applet
public class ThreadedColorBounce extends [Link] implements Runnable { Ball b; Thread t; public void init() { b = new Ball(); setBackground([Link]); } public void start() { if ( t == null) { t = new Thread(this); [Link](); }} ...
cs480 (Prasad) L11Threads 7
public void stop() { t = null; } public void paint([Link] g) { [Link](g); } public void run() { try { while (true) { [Link](15); repaint(); } } catch (InterruptedException e) {}; } }
cs480 (Prasad) L11Threads 8
Color Changing Ball
class ColorBall extends Thread { static final int TOP = 10, BOTTOM = 150; [Link] c = [Link]; int incr = 2; int ypos = TOP; public ColorBall(){ start(); } void paint([Link] g) { if (ypos < TOP || ypos > BOTTOM) incr= -incr; ypos += incr; [Link](c); [Link](10,ypos, 10,10); }
cs480 (Prasad)
...
L11Threads 9
...
public void run() { try { while (true) { sleep(600); c = new [Link]( (float) [Link](), (float) [Link](), (float) [Link]() ); } } catch (InterruptedException e) {}; } }
cs480 (Prasad) L11Threads 10
Mutual Exclusion
Sharing Data
cs480 (Prasad)
L11Threads
11
Threads Sharing Data
class Shared { private int cnt = 0; // synchronized void print(String Id) { [Link](Id + : + cnt ); [Link]( - + ++cnt); } } class Shared { private int cnt = 0; void print(String Id) { synchronized (this) { [Link](Id + : + cnt ); [Link]( - + ++cnt); } } }
cs480 (Prasad) L11Threads 12
class SharingThread extends Thread { private static Shared s = new Shared(); String Id; SharingThread (String Name) { Id = Name; start(); } public void run () { while (true) { [Link](Id); // yield(); } } public static void main (String [] args) { new SharingThread( A ) ; new SharingThread( B ) ; } }
cs480 (Prasad)
L11Threads
13
Motivation for Mutual Exclusion
Concurrent Access A:368-369
A:369-370
B:370-371
A:370-372
A:372-373
A:373-374
A:374-375
B:371-376
B:376-377
B:377-378
B:378-379
[Link]-381
A:381-382
A:382-383
A:383-384
-380
cs480 (Prasad)
Mutual Exclusion with yield()
A:693-694
A:694-695
A:695-696
B:696-697
B:697-698
B:698-699
B:699-700
B:700-701
B:701-702
A:702-703
A:703-704
A:704-705
A:705-706
...
A:828-829
B:829-830
B:830-831
A:831-832
B:832-833
A:833-834
B:834-835
A:835-836
B:836-837
B:837-838
A:838-839
B:839-840
L11Threads
14
// C# using using class
Equivalent System; [Link]; Shared { private int cnt = 0; public void print(String Id) { lock (this) { [Link](Id + ":" + cnt); [Link]("-" + ++cnt); }; }
} class SharingThread { private static Shared s = new Shared(); String Id; SharingThread (String Name) { Id = Name; } public void run () { while (true) { [Link](Id); } } public static void Main (string [] args) { new Thread (new ThreadStart (new SharingThread("A").run) ). Start() ; new Thread (new ThreadStart (new SharingThread("B").run) ). Start() ; } }
cs480 (Prasad)
L11Threads
15
Interaction of Language Features
run() method case study
cs480 (Prasad)
L11Threads
16
Subclassing : Access Control
class Thread { ... public void run() { } } class SubThread extends Thread { public void run() { ... Thread t = new SubThread(); [Link]() }
/******************ILLEGAL******************** void run() { ... } *******************ILLEGAL********************/ }
Otherwise, run() can be invoked on a SubThread instance via (its reference in) a Thread variable (due to dynamic binding) in another package.
cs480 (Prasad) L11Threads 17
Subclassing :
Exception
Thread t = new SubThread(); [Link]() }
class Thread { ... public void run() { } } class SubThread extends Thread { public void run() { ...
/******************ILLEGAL******************** public void run() throws InterruptedException { sleep(1000); } *******************ILLEGAL********************/ } run() invoked on a SubThread instance via a Thread
variable (by dynamic binding) can violate the contract that run() of class Thread does not throw any exception.
cs480 (Prasad)
L11Threads
18
Subclassing : synchronized
A synchronized method can override or be overridden by a non-synchronized method. However, this does not alter synchronized -status of the overridden method accessible using super. The locks are released when synchronized statements and synchronized method invocations complete abruptly by throwing an exception. v Incorporating threads in the language enables dealing with problematic interactions with other language features.
cs480 (Prasad)
L11Threads
19
synchronized
methods
A method that is not synchronized can run concurrently with a synchronized method on behalf of different threads.
The locking -analogy breaks down here. For concreteness, consider an example involving two threads: (i) T1 running synchronized method m1 and (ii) T2 running ordinary method m2 on the same object O.
A synchronized method can call another synchronized method in the same thread.
Recursion meaningful
cs480 (Prasad) L11Threads 20
synchronized
methods
A synchronized instance (resp. static) method locks instance (resp. static) fields.
A synchronized instance method does not protect static fields, and they can corrupt it thro an update. For concreteness, consider an example involving two threads T1 and T2 running synchronized instance methods m1 and m2 on objects O1 and O2 of the same class C. Both m1 and m2 are permitted to concurrently access the static fields of C, and there is potential for corruption. In such situations, static fields must be accessed in the body of instance methods using calls to synchronized static methods.
cs480 (Prasad) L11Threads 21
Thread Scheduling
cs480 (Prasad)
L11Threads
22
Blocked Thread
A thread is blocked (that is, it is not runnable) if it is:
sleeping. suspended. waiting. executing a blocked method. blocked for I/O.
Java neither detects nor prevents deadlocks.
cs480 (Prasad)
L11Threads
23
Thread Scheduling
Java runs a non-blocked (runnable) highest-priority thread. A thread can be preempted by a higher priority thread that becomes runnable.
The scheduler may however choose to run lower priority thread, to avoid starvation.
The same (highest) priority threads are run in round-robin fashion.
cs480 (Prasad) L11Threads 24
Scheduling Ambiguity
JVM on Windows uses time-slicing to schedule same priority threads. ( Fair policy ) JVM on Solaris chooses one of the same priority threads to run until the thread voluntarily relinquishes the CPU (by sleeping, yielding, or exiting), or until a higher priority thread preempts it.
cs480 (Prasad) L11Threads 25
Cooperative Concurrent Threads
Producer-Consumer Problem Bounded-Buffer Problem (Clients and Servers : Resource Sharing)
cs480 (Prasad)
L11Threads
26
Simplistic 1-Cell Buffer
class Buffer { Object x; // synchronized public void put (Object _x, String id) { [Link]( "Done << " + id + " puts " + _x); x = _x; } // synchronized public Object get (String id) { [Link]( "Done >> " + id + " gets " + x); return x; } }
cs480 (Prasad)
L11Threads
27
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 = [Link]([Link]() % 1999) + 50; sleep(delay); ir = new Integer(delay);
[Link]("Ready << "+id+" puts "+ ir);
[Link](ir, id);
}catch } } }
(Exception e){[Link]("Exception$ " + e);};
cs480 (Prasad)
L11Threads
28
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 = [Link]([Link]() % 1999) + 50; sleep(delay);
[Link]("Ready >> " + id + " gets ");
ir = (Integer) } } } }
cs480 (Prasad)
[Link](id);
catch (Exception e) {[Link]("Exception$ " + e);};
L11Threads
29
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 {[Link](1000); } catch (Exception e){}; new Consumer(b,"C2") . start(); new Producer(b,"P2") . start(); } }
cs480 (Prasad) L11Threads 30