View
225
Download
0
Category
Preview:
Citation preview
CS884 (Prasad) java8Threads 2
• Multiprocessing– Using Multiple Processors.
• Multiprogramming (Batch)– Switch and execute different jobs simultaneously,
to improve CPU utilization.• Multitasking (Interactive)
– Perform more than one task at a time for each user, to improve response time.
• Multithreading– Threads in a user task (process) can share code, data,
and system resources, and access them concurrently. Each thread has a separate program counter, registers,
and a run-time stack.
CS884 (Prasad) java8Threads 3
Threads• A single sequential flow of control (of
execution of expressions and statements) is called a thread.
• A thread independently executes Java code, but may share address space with others. (cf. Process)– In Java, class/instance variables, and array
components are shareable among threads; local variables and formal parameters are not.
CS884 (Prasad) java8Threads 4
Multithreading is general, convenient, & efficient
paradigm for implementing interactive systems.
• Independent/cooperating input/processing/display
activities.
• In single-threaded systems, each application is
responsible for interleaving these activities through
polling or interrupts.
• In multi-threaded systems, these activities are
interleaved using a general time-slicing external to
the application.
CS884 (Prasad) java8Threads 5
Multithreading on uni-processor • ConsCons: Thread scheduling overheads.
• ProsPros:
� Concurrency necessary for natural description and fair execution of applications involving shared resources. Multithreaded systems reduce programmer burden by factoring out scheduling.
� Improves resource utilization as it incorporates demand-based scheduling and prevents starvation.
� Improves responsiveness in interactive systems by assigning priorities to threads and using preemption.
� Enables flexible control of one thread from another thread. (E.g., stop, suspend, resume etc.)
CS884 (Prasad) java8Threads 6
Further Multi-threading Examples
• In multimedia applications (e.g., playing audio and/or video concurrently).
• Performing I/O concurrently with scrolling a document (e.g., downloading image with a separate “controller” thread).
• Periodic updating of the screen with data acquired in real-time (e.g., Sports Ticker, Stock Quotes, Advertisements, etc.).
CS884 (Prasad) java8Threads 8
• Mutual exclusion construct is based on Hoare’s monitor.
• synchronized methods in a class cannot be run concurrently on behalf of different threads.
• Recursive call or Calls to synchronized methods permitted in the same thread.
• synchronized statement locks an object.• “Object” is an instance of a class (incl. class Class).
• To synchronize “producers” and “consumers” Hoare uses wait/signal on condition variables.
• wait() / notify() / notifyAll() etc. enable threads to communicate/regulate each other’s progress.
CS884 (Prasad) java8Threads 9
Creating and Running Threads• Define subclass of class Thread.
Override run() method.• public void run() { }
• Create an instance of the subclass, and invoke start() on it. Now run() method executes in an independent thread.
• Threads can also be created from an instance of a class implementing the interface Runnable.
• Required when the class is defined by extension.
CS884 (Prasad) java8Threads 10
Example using class Threadclass Echo extends Thread { public void run() { while (true) System.out.println(“ABC”); } public static void main (String[] args) { new Echo() . start(); new Echo() . start(); }}
CS884 (Prasad) java8Threads 11
1 ABC1 ABC1 ABC1 ABC2 ABC2 ABC2 ABC2 ABC2 ABC1 ABC1 ABC2 ABC2 ABC2 ABC1 ABC . . .
> javac Echo.java > java Echo
1 ABC2 ABC2 ABC2 ABC1 ABC1 ABC2 ABC2 ABC2 ABC2 ABC2 ABC1 ABC1 ABC1 ABC
...
1 ABC1 ABC1 ABC1 ABC1 ABC1 ABC1 ABC1 ABC1 ABC
...
Solaris
Windows
with yield() in both OS
1 ABC2 ABC1 ABC2ABC1 ABC2 ABC1ABC2 ABC1 ABC2 ABC
...
CS884 (Prasad) java8Threads 12
Example using interface Runnableclass Echo implements Runnable { public void run() { try { while (true) { Thread.sleep(10); System.out.println(“ABC”); } } catch (InterruptedException e) { return; } } public static void main (String[] args) { Runnable r = new Echo(); new Thread(r) . start(); }}
CS884 (Prasad) java8Threads 13
Example of Sharingclass Shared { private int cnt = 0; void print(String Id) { synchronized (this) { System.out.print(Id + “:” + cnt ); System.out.println( “-” + ++cnt); } }}
class Shared { private int cnt = 0; synchronized void print(String Id) { System.out.print(Id + “:” + cnt ); System.out.println( “-” + ++cnt); }}
CS884 (Prasad) java8Threads 14
Threads sharing an object
class SharingThread extends Thread {
private static Shared s = new Shared();
String Id;
SharingThread (String Name) { Id = Name;
start();}
public void run () { while (true) { s.print(Id); } }
public static void main (String [] args) {
new SharingThread(“A”) ;
new SharingThread(“B”) ; }
}
CS884 (Prasad) java8Threads 15
Motivation for Mutual ExclusionConcurrent AccessConcurrent Access Mutual Exclusion with yield()
A:368-369A:369-370B:370-371A:370-372A:372-373A:373-374A:374-375B:371-376B:376-377B:377-378B:378-379B:379A:375-381A:381-382A:382-383A:383-384-380
A:828-829B:829-830B:830-831A:831-832B:832-833A:833-834B:834-835A:835-836B:836-837B:837-838A:838-839B:839-840
…
A:693-694A:694-695A:695-696B:696-697B:697-698B:698-699B:699-700B:700-701B:701-702A:702-703A:703-704A:704-705A:705-706
...
cs480 (Prasad) L11Threads 17
Subclassing : Access Control class Thread { ... public void run() { }}class SubThread extends Thread { public void run() { ... }
// ILLEGAL // void run() { ... }
}
• 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 18
Subclassing : Exception class Thread { ... public void run() { }}class SubThread extends Thread { public void run() { ... }
// ILLEGAL // public void run() throws InterruptedException { // sleep(1000); }
}
• Otherwise,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.
CS884 (Prasad) java8Threads 19
Synchronized• It is illegal to use synchronized for constructors and for
method declarations in interfaces. • Can abstract methods be 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.
CS884 (Prasad) java8Threads 20
Synchronized Methods• When two threads invoke synchronized instance
(static) methods simultaneously on the same object, only one thread is permitted exclusive access to the instance (static) fields of the object (class).
• When two threads invoke synchronized instance methods simultaneously on the same object, the static fields of the class are not locked.
• A thread can access fields of an object using a non-synchronized method even when the object is locked by another thread executing a synchronized method.
CS884 (Prasad) java8Threads 21
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() {...}• Notifies all the threads waiting on this object.
These methods must be invoked inside synchronized code or else IllegalMonitorStateException will be thrown.
CS884 (Prasad) java8Threads 23
Simplistic 1-Cell Bufferclass 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; }}
CS884 (Prasad) java8Threads 24
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 (Exception e){System.out.println("Exception$ " + e);};
}}
CS884 (Prasad) java8Threads 25
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) b.get(id); } } catch (Exception e) {System.out.println("Exception$ " + e);};
}}
CS884 (Prasad) java8Threads 26
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();
}}
CS884 (Prasad) java8Threads 27
Unfettered Run
Ready >> C1 getsReady << P2 puts 493Done >> C1 gets nullDone << P2 puts 493Ready << P1 puts 1591Done << P1 puts 1591Ready << P1 puts 488Done << P1 puts 488Ready >> C2 getsDone >> C2 gets 488Ready >> C1 getsDone >> C1 gets 488Ready >> C2 getsDone >> C2 gets 488Ready << P1 puts 745Done << P1 puts 745 ...
...Ready << P2 puts 815Done << P2 puts 815Ready >> C2 getsDone >> C2 gets 815Ready << P1 puts 1223Done << P1 puts 1223Ready >> C1 getsDone >> C1 gets 1223Ready << P2 puts 403Done << P2 puts 403Ready >> C2 getsDone >> C2 gets 403 ...
(transient stability?!)
CS884 (Prasad) java8Threads 28
Concurrency controlConcurrency 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.
• A consumer (producer) is not permitted to get (put) an item from (into) buffer if empty (full).
CS884 (Prasad) java8Threads 29
public synchronized void
put (Object _x, String id) throws Exception {
while (!empty) wait();
empty = ! empty;
System.out.println("Done << "+id+" puts "+ _x);
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”)
CS884 (Prasad) java8Threads 30
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 a buffer element to read.
CS884 (Prasad) java8Threads 31
Synchonization and Mutual Exclusion
Ready >> C2 getsReady >> C1 getsReady << P1 puts 1672Done << P1 puts 1672Done >> C2 gets 1672Ready << P2 puts 774Done << P2 puts 774Done >> C1 gets 774Ready << P1 puts 168Done << P1 puts 168Ready >> C1 getsDone >> C1 gets 168Ready << P2 puts 1263Done << P2 puts 1263Ready >> C1 getsDone >> C1 gets 1263 …
...Ready << P1 puts 622Done << P1 puts 622Ready >> C1 getsDone >> C1 gets 622Ready >> C2 getsReady << P2 puts 1447Done << P2 puts 1447Done >> C2 gets 1447Ready << P2 puts 96Done << P2 puts 96Ready << P2 puts 95Ready >> C1 getsDone >> C1 gets 96Done << P2 puts 95 ...
CS884 (Prasad) java8Threads 33
Bounded Buffer class Queue { private int c, front = 0, rear = 0, count = 0; private int [] q; Queue(int capacity) { c = capacity; q = new int [c]; } public synchronized void insert (int i) throws InterruptedException { … } public synchronized int delete () throws InterruptedException { … }
}
CS884 (Prasad) java8Threads 34
public synchronized void insert (int i) throws InterruptedException {
while (count == c) wait(); q[rear] = i; rear = (++rear) % c; count++; notifyAll(); } public synchronized int delete () throws InterruptedException { while (count == 0) wait(); --count; notifyAll(); int t = front; front = (++front) % c; return q[t]; }
CS884 (Prasad) java8Threads 35
Producerclass ProducerThread extends Thread {
private String Id;
private Queue buf;
private int init;
ProducerThread(String Name,Queue q,int i) {
Id = Name;
buf = q;
init = i;
}
public void run() { … }
}
CS884 (Prasad) java8Threads 36
public void run() {
try {
while (true) {
sleep(10); System.out.println("Produced by " +
Id + " " + init);
buf.insert(init++);
}
} catch (InterruptedException e) { System.exit(0);
}
}
CS884 (Prasad) java8Threads 37
Consumerclass ConsumerThread extends Thread {
private String Id;
private Queue buf;
ConsumerThread (String Name, Queue q ) {
Id = Name;
buf = q;
}
public void run() { … }
}
CS884 (Prasad) java8Threads 38
public void run() {
try {
while (true) {
sleep( (new java.util.Random()).nextInt() % 19 ); System.out.println("Consumed by " + Id
+ buf.delete());
}
} catch (InterruptedException e) { System.exit(0);
}
}
CS884 (Prasad) java8Threads 39
Driver Programpublic class TestBuffer { static Queue buffer = new Queue(11);
public static void main (String [] args) { ProducerThread p1 =
new ProducerThread("P1:", buffer, 0); ProducerThread p2 =
new ProducerThread("P2:", buffer, 10000); ConsumerThread c1 =
new ConsumerThread("C1:", buffer); ConsumerThread c2 =
new ConsumerThread("C2:", buffer); p1.start();
p2.start(); c1.start();
c2.start(); }}
CS884 (Prasad) java8Threads 41
Thread Priority • Range : MIN_PRIORITY ... NORM_PRIORITY ... MAX_PRIORITY
• A thread inherits its creator’s priority. It can be inspected (changed) at any time using getPriority (setPriority).
• Generally, the continuously running part of an application should run in a lower-priority thread, while the thread dealing with rarer events such as user input should have higher-priority.
• When a thread dies, its object does not go away, so its state can still be accessed.
CS884 (Prasad) java8Threads 43
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. • Other Methods:
– yield(), join(), etc.
CS884 (Prasad) java8Threads 44
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.
CS884 (Prasad) java8Threads 45
• 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.
CS884 (Prasad) java8Threads 46
Kinds of Thread • User and Daemon.
• Each application starts off as a user thread (main()).
• A thread’s status can be inspected (changed to daemon
before starting it ) using getDaemon() (setDaemon(true)).
• Threads inherit user/daemon status from their creator.
• An application runs until all user threads have completed.
When the last user thread completes, any remaining
daemon threads are stopped.
– To make the application exit when the original thread
dies, mark all the created threads daemon.
CS884 (Prasad) java8Threads 47
Example: Non-determinism class Sample { int a = 1, b = 2; void h() { a = b + 10; } void t() { b = a + 100;} }If two different threads concurrently execute h() and t(), then• If h() and t() are synchronized, then the post condition is:
– ( a = 12 b = 11( b = 101 a = 111• If h() and t() are not synchronized, then: (“non-exhaustive”)
– If all vars written back: ...( a = 12 b = 101– If all vars not written back: ( a = 1 b =
( a = 12 b = 2 ( a = 1 b = 101
CS884 (Prasad) java8Threads 48
Example: Out-of-order writes class Simple { int a = 1, b = 2; void synchronized t() { a = 3; b = 4; } void f() { System.out.println(a + “ ” + b); } }• assign a (use a) precedes assign b (use b) in t() (f()).• t() synchronized, so both a and b written back finally.• f() not synchronized, so its actions interleaved with t()’s.• No restrictions on the order of reads / writes of different
variables from memory.
– f(): read(a), t(): write(a), t(): write(b), f(): read(b);
– Finally: a = 3 and b = 4.
– Printed: 1 4
Recommended