Presentation is loading. Please wait.

Presentation is loading. Please wait.

MultiThreading Programming

Similar presentations


Presentation on theme: "MultiThreading Programming"— Presentation transcript:

1 MultiThreading Programming
Object-Oriented Technology and Development

2 Thread Objectives Understand basic concurrency terminology
Create active Java objects using the Runnable interface and Thread class Write Java objects that are thread safe Synchronized methods and object locking Understand concurrency concepts including thread groups, liveness vs. safety, and nondeterminism Know tradeoffs between JVM thread implementations Understand periodic and aperiodic tasks and how to use the Java Timer to perform scheduling

3 Concurrency Terminology
Simple Process executes until it surrenders CPU Blocking operations (I/O) may force surrender Time-slicing Process executes for period of time, then surrenders CPU Priority Processes have priorities, higher executes before lower Preemption Process with higher priority will interrupt lower Round-robin A process will not execute until all others have executed Commonly used with priorities

4 Threads Operating systems provide concurrent processes
Each process contains its own data and stack Threads are processes within a single OS process Sometimes called "lightweight processes" Threads share the data of the parent processes Object created by one thread is visible to another Threads have their own stack for local variables

5 Thread Example class Proc extends Thread { protected int id; public Proc (int assignedID) { id = assignedID; } public void run() { for (int loop=0; loop < 5; loop++) System.out.println("Hello from " + id + " loop=" + loop); class Main { public static void main(String args[]) { int times= (new Integer(args[0])).intValue(); for (int loop=0; loop < times; loop++) { Thread p = new Proc(loop); p.start();

6 Thread Example Output Threads may execute in any order
Hello from 0 loop=0 Hello from 1 loop=0 Hello from 2 loop=0 Hello from 2 loop=1 Hello from 0 loop=1 Hello from 0 loop=2 Hello from 0 loop=3 Hello from 1 loop=1 Hello from 1 loop=2 Hello from 1 loop=3 Hello from 2 loop=2 Hello from 2 loop=3 Hello from 0 loop=4 Hello from 2 loop=4 Hello from 1 loop=4 Threads may execute in any order

7 Class Thread: An Overview of the Thread Methods
Class Thread constructors public Thread( String threadName ) public Thread() Code for thread in thread’s run method Method sleep makes thread inactive Method interrupt interrupts a running thread Method isAlive checks status of a thread Method setName sets a thread’s name Method join Waits for thread to finish and continues from current thread

8 Threaded States: Life Cycle of a Thread
Thread states Born state Thread was just created Ready state Thread’s start method invoked Thread can now execute Running state Thread is assigned a processor and running Dead state Thread has completed or exited Eventually disposed of by system

9 Thread States: Life Cycle of a Thread
State diagram showing the Life cycle of a thread.

10 Creating Java Threads Two mechanisms for creating active Java objects
1) Derive from class Thread 2) Implement Runnable interface Runnable defines a protocol for active objects Contains a single method "void run()" Thread defines a thread implementation Thread implements Runnable

11 Thread Properties Thread Methods Thread States
run() code to execute for thread start() called by client to begin thread's execution sleep(long) suspends thread for # milliseconds yield() forces scheduling to occur Thread States new after new is called on a threaded class creates thread, but does not begin execution runnable after start() is called (blocked, sleep, suspend, wait) dead completed

12 Thread Priorities and Thread Scheduling
Priorities defined between one and ten (high) Five is default Scheduling is preemptive, round-robin Time Slicing Not guaranteed (Solaris: no, Windows 95/NT: yes) Threads without blocking calls (I/O) can run forever User should call yield() to be kind to other threads Typically, programmer not concerned with scheduling

13 Shared Data Access Objects are visible to multiple threads
What if two threads access data simultaneously? ActiveObject1 executes a method on SharedObject Before method completion, ActiveObject2 calls the method Potential "race condition" SharedObject's state may become inconsistent :ActiveObject1 :SharedObject :ActiveObject2

14 Monitors Solution: turn a Java class into a monitor Monitor semantics
Monitors are a synchronization mechanism defined by Hoare (Communicating Sequential Processes) Monitor semantics Clients must gain a lock on the monitor object before invoking methods Clients waiting for the lock are placed in a queue A client with a lock may surrender the lock without "leaving" the object May later resume execution after re-obtaining the lock

15 Monitors in Java Synchronized methods create monitors
class Account { public synchronized deposit (Account a, int amount); public synchronized withdraw (Account a, int amount); public int balance(); } Synchronized methods lock the object during their execution Objects with synchronized methods have a queue of waiting threads Static methods need only obtain the class lock Non-static methods must lock the object and the class

16 Synchronization Example
:Proc :Data :Proc access :Proc class Synchronization { public static void main(String args[]) { Data theDataItem = new Data(); for (int i=1; i <= 3; i++){ Thread p = new Proc(i, theDataItem); p.start(); } Creating 3 threads

17 Synchronization Example: Thread
class Proc extends Thread { private int id; private Data theData; public Proc(int x, Data d) { id = x; theData = d; } public void run() { System.out.println("Thread started #" + id); try { for (int i = 0; i < 3; i++) { theData.access(id, i); yield(); catch (Exception e) {e.printStackTrace();}

18 Synchronization Example: Data
class Data { synchronized public void access(int who, int count) { System.out.println(this + " data object accessed by " + who + " count is " + count); }

19 Example Outputs Thread started #1 Thread started #3
data object accessed by 1 count is 0 Thread started #2 data object accessed by 3 count is 0 data object accessed by 3 count is 1 data object accessed by 2 count is 0 data object accessed by 2 count is 1 data object accessed by 1 count is 1 data object accessed by 1 count is 2 data object accessed by 3 count is 2 data object accessed by 2 count is 2

20 Guarded Entries Object may not be able to grant request
Do not want client to retry operation which is analogous to polling and too inefficient Solution is a monitor with guarded entries protected type bank function balance; procedure deposit; //signals state change procedure withdraw (amount) [when (amount <= balance)] end bank; :Bank :Client1 balance deposit :Client2 withdraw

21 Waiting Example Java implements guarded monitors with wait()/notify()
class Bank { private float balance; synchronized void withdraw (float amount) { try { while (amount > balance) wait(); } catch(InterruptedException e) { e.printStackTrace(); } balance = balance - amount; synchronized void deposit (float amount) { balance = balance + amount; notify(); float balance() { return balance; }

22 Explicit Locking Java provides two mechanism to lock an object
Synchronized methods on the object's class A synchronized block synchronized (<object>) { // obtain lock on <object> <object>.changeState(); } Synchronized blocks obtain the object's lock Responsibility is placed on the caller, not the object implementation Potential source for errors in concurrent program

23 The Runnable Interface
Java's second mechanism to implement concurrency Not all classes can extend thread (may already be a subclass) Any class can implement Runnable Must provide a run() method Instances are not by default concurrent threads Must create a Thread instance

24 Runnable Example class Proc implements Runnable { <same as before> } class Main { public static void main(String args[]) { int times = (new Integer(args[0])).intValue(); for (int loop=0; loop < times; loop++) { Runnable runner = new Proc(loop); Thread proc = new Thread(runner); proc.start();

25 Thread Groups Coordinate startup and shutdown of threads
Want to initialize all threads before beginning their execution Increase performance by using single call to affect thread state Java thread groups Hierarchical, groups can contain other groups Organized by name The default group is “main” Have independent max/min priorities, security permissions, stop/start/suspend/resume

26 Thread Groups Class ThreadGroup Parent and child thread groups
Create and manipulate groups of threads Each group has unique name at creation Parent and child thread groups Method calls sent to parent group also sent to child groups

27 Groups Example aGroup.suspend(); bGroup.suspend();
class Groups { public static void main(String args[]) throws Exception { Thread.currentThread().setPriority (Thread.MAX_PRIORITY); ThreadGroup aGroup = new ThreadGroup("A"); aGroup.setMaxPriority(5); ThreadGroup bGroup = new ThreadGroup("B"); bGroup.setMaxPriority(5); for (int i=1; i <= 3; i++) { Thread p = new Thread(aGroup, new Proc(i)); p.start(); p = new Thread(bGroup, new Proc(i*10)); } aGroup.suspend(); bGroup.suspend(); System.out.println("Group A"); aGroup.resume(); Thread.sleep(90); System.out.println("Group A and B"); bGroup.resume(); Thread.sleep(90); System.out.println("None"); aGroup.stop(); bGroup.stop();

28 Groups Example class Proc implements Runnable { private int id;
public Proc(int x) {id = x;} public void run() { try { while (true) { System.out.println("Hello from " + id); Thread.yield(); } catch (Exception e) {e.printStackTrace();}

29 Example Output Group A Hello from 1 Hello from 2 Hello from 3 Group A and B Hello from 10 Hello from 20 Hello from 30 None

30 Concurrency Limitations
Safety Threads must synchronize access to resources Liveness Activities may fail to execute because of deadlock, too much synchronization, or not enough CPU cycles (starvation) Nondeterminism Concurrent program have many (possibly infinite) executions Thread vs. method call efficiency Not all messages are asynchronous Constructing a thread to handle a message is much slower than invoking an object’s method

31 Liveness Prevention Contention Dormancy Deadlock
Other processes and threads utilizing CPU Dormancy Thread fails to become runnable (wait() with no notify()) Deadlock Waiting for a resource which will never become available All threads should allocate resource in same order

32 JVM Thread Implementations
Native vs. non-native (e.g., “green” threads) Native: thread resources managed (scheduled) by underlying OS Non-native: threads managed by JVM, JVM is simply an OS process Native advantages Leverage multiprocessor hardware Can use thread libraries written in other languages VM can avoid inefficient I/O calls required by green threads

33 Scheduling Issues Ensure all threads (tasks) have sufficient CPU cycles Periodic/Aperiodic Tasks Periodic tasks execute on a regular schedule Take a temperature reading from a sensor every 100 ms Aperiodic tasks execute as response to an event User selects “spell check” Task types Execution: at precise date/time or after specified delay Periodic: execute every …

34 Java’s Timer Classes Timers schedule tasks (threads) for future background execution Java timer-related classes Timer Schedules tasks for execution TimerTask Base Class for all tasks scheduled by a Timer

35 Timer Example import java.util.*; class TimerExample { public static void main(String args[]) throws Exception { Timer timer = new Timer(); timer.schedule(new MyTask(1), 4000); timer.schedule(new MyTask(2), 2000); for (int i=0; i < 5; i++) { System.out.println("tick"); Thread.sleep(1000); } //Periodic tasks timer.scheduleAtFixedRate(new MyTask(3), 0, 500); timer.scheduleAtFixedRate(new MyTask(4), 0, 200); timer.cancel(); class MyTask extends TimerTask { int id; public MyTask(int myId) {id = myId;} public void run() {System.out.println("Executed #" + id);}

36 Timer Example Output tick Executed #2 // executed once after 2 seconds

37 Thread Synchronization (Revisited)
Java uses monitors for thread synchronization The sychronized keyword Every synchronized method of an object has a monitor One thread inside a synchronized method at a time All other threads block until method finishes Next highest priority thread runs when method finishes

38 Producer/Consumer Relationship without Synchronization
Buffer Shared memory region Producer thread Calls produce method to add item to buffer Calls wait if consumer has not read last message in buffer Writes to empty buffer and calls notify for consumer Consumer thread Reads message from buffer Calls wait if buffer empty Synchronize threads to avoid corrupted data

39 1 ProduceInteger.java 2 // Definition of threaded class ProduceInteger 3 public class ProduceInteger extends Thread { private HoldIntegerUnsynchronized sharedObject; 5 // initialize ProduceInteger thread object public ProduceInteger( HoldIntegerUnsynchronized shared ) { super( "ProduceInteger" ); sharedObject = shared; } // ProduceInteger thread loops 10 times and calls // sharedObject's setSharedInt method each time public void run() { for ( int count = 1; count <= 10; count++ ) { 18 // sleep for a random interval try { Thread.sleep( ( int ) ( Math.random() * 3000 ) ); } 23 24

40 33 // process InterruptedException during sleep
catch( InterruptedException exception ) { System.err.println( exception.toString() ); } // call sharedObject method from this // thread of execution sharedObject.setSharedInt( count ); } System.err.println( getName() + " finished producing values" + "\nTerminating " + getName() ); } 38 39 } // end class ProduceInteger

41 1 // ConsumeInteger.java
2 // Definition of threaded class ConsumeInteger 3 public class ConsumeInteger extends Thread { private HoldIntegerUnsynchronized sharedObject; 5 // initialize ConsumerInteger thread object public ConsumeInteger( HoldIntegerUnsynchronized shared ) { super( "ConsumeInteger" ); sharedObject = shared; } 12 // ConsumeInteger thread loops until it receives 10 // from sharedObject's getSharedInt method public void run() { int value, sum = 0; 18 do { 20 // sleep for a random interval try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } 25 26

42 35 // process InterruptedException during sleep
catch( InterruptedException exception ) { System.err.println( exception.toString() ); } 30 value = sharedObject.getSharedInt(); sum += value; 33 } while ( value != 10 ); System.err.println( getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() ); } 40 41 } // end class ConsumeInteger

43 1 // HoldIntegerUnsynchronized.java
2 // Definition of class HoldIntegerUnsynchronized. 3 public class HoldIntegerUnsynchronized { private int sharedInt = -1; 5 // unsynchronized method to place value in sharedInt public void setSharedInt( int value ) { System.err.println( Thread.currentThread().getName() + " setting sharedInt to " + value ); 11 sharedInt = value; } 14 // unsynchronized method return sharedInt's value public int getSharedInt() { System.err.println( Thread.currentThread().getName() + " retrieving sharedInt value " + sharedInt ); 20 return sharedInt; } 23 24 } // end class HoldIntegerUnsynchronized

44 1 // SharedCell.java 2 // Show multiple threads modifying shared object. 3 public class SharedCell { 4 // execute application public static void main( String args[] ) { HoldIntegerUnsynchronized sharedObject = new HoldIntegerUnsynchronized(); 10 // create threads ProduceInteger producer = new ProduceInteger( sharedObject ); ConsumeInteger consumer = new ConsumeInteger( sharedObject ); 16 // start threads producer.start(); consumer.start(); } 21 22 } // end class SharedCell

45 ConsumeInteger retrieving sharedInt value -1
ProduceInteger setting sharedInt to 1 ProduceInteger setting sharedInt to 2 ConsumeInteger retrieving sharedInt value 2 ProduceInteger setting sharedInt to 3 ProduceInteger setting sharedInt to 4 ProduceInteger setting sharedInt to 5 ConsumeInteger retrieving sharedInt value 5 ProduceInteger setting sharedInt to 6 ProduceInteger setting sharedInt to 7 ProduceInteger setting sharedInt to 8 ConsumeInteger retrieving sharedInt value 8 ProduceInteger setting sharedInt to 9 ConsumeInteger retrieving sharedInt value 9 ProduceInteger setting sharedInt to 10 ProduceInteger finished producing values Terminating ProduceInteger ConsumeInteger retrieving sharedInt value 10 ConsumeInteger retrieved values totaling: 49 Terminating ConsumeInteger

46 Producer/Consumer Relationship with Thread Synchronization
Synchronize threads to ensure correct data

47 1 // ProduceInteger.java
2 // Definition of threaded class ProduceInteger 3 public class ProduceInteger extends Thread { private HoldIntegerSynchronized sharedObject; 5 // initialize ProduceInteger thread object public ProduceInteger( HoldIntegerSynchronized shared ) { super( "ProduceInteger" ); sharedObject = shared; } 12 // ProduceInteger thread loops 10 times and calls // sharedObject's setSharedInt method each time public void run() { for ( int count = 1; count <= 10; count++ ) { 18 // sleep for a random interval try { Thread.sleep( ( int ) ( Math.random() * 3000 ) ); } 23 24

48 34 // process InterruptedException during sleep
catch( InterruptedException exception ) { System.err.println( exception.toString() ); } 28 // call sharedObject method from this // thread of execution sharedObject.setSharedInt( count ); } 33 System.err.println( getName() + " finished producing values" + "\nTerminating " + getName() ); } 38 39 } // end class ProduceInteger

49 1 // ConsumeInteger.java
2 // Definition of threaded class ConsumeInteger 3 public class ConsumeInteger extends Thread { private HoldIntegerSynchronized sharedObject; 5 // initialize ConsumerInteger thread object public ConsumeInteger( HoldIntegerSynchronized shared ) { super( "ConsumeInteger" ); sharedObject = shared; } 12 // ConsumeInteger thread loops until it receives 10 // from sharedObject's getSharedInt method public void run() { int value, sum = 0; 18 do { 20 // sleep for a random interval try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } 25 26

50 35 // process InterruptedException during sleep
catch( InterruptedException exception ) { System.err.println( exception.toString() ); } 30 value = sharedObject.getSharedInt(); sum += value; 33 } while ( value != 10 ); System.err.println( getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() ); } 40 41 } // end class ConsumeInteger

51 1 // HoldIntegerSynchronized.java
2 // Definition of class HoldIntegerSynchronized that 3 // uses thread synchronization to ensure that both 4 // threads access sharedInt at the proper times. 5 public class HoldIntegerSynchronized { private int sharedInt = -1; private boolean writeable = true; // condition variable 8 // synchronized method allows only one thread at a time to // invoke this method to set the value for a particular // HoldIntegerSynchronized object public synchronized void setSharedInt( int value ) { while ( !writeable ) { // not the producer's turn 15 // thread that called this method must wait try { wait(); } 20 // process Interrupted exception while thread waiting catch ( InterruptedException exception ) { exception.printStackTrace(); } } 26 System.err.println( Thread.currentThread().getName() + " setting sharedInt to " + value ); 29 // set new sharedInt value sharedInt = value; 32

52 33 // indicate that producer cannot store another value until
// a consumer retrieve current sharedInt value writeable = false; 36 // tell a waiting thread to become ready notify(); } 40 // synchronized method allows only one thread at a time to // invoke this method to get the value for a particular // HoldIntegerSynchronized object public synchronized int getSharedInt() { while ( writeable ) { // not the consumer's turn 47 // thread that called this method must wait try { wait(); } 52 // process Interrupted exception while thread waiting catch ( InterruptedException exception ) { exception.printStackTrace(); } } 58 59

53 68 // indicate that producer cant store another value
// because a consumer just retrieved sharedInt value writeable = true; 62 // tell a waiting thread to become ready notify(); 65 System.err.println( Thread.currentThread().getName() + " retrieving sharedInt value " + sharedInt ); return sharedInt; } 71 72 } // end class HoldIntegerSynchronized

54 1 // SharedCell.java 2 // Show multiple threads modifying shared object. 3 public class SharedCell { 4 // execute application public static void main( String args[] ) { HoldIntegerSynchronized sharedObject = new HoldIntegerSynchronized(); 10 // create threads ProduceInteger producer = new ProduceInteger( sharedObject ); ConsumeInteger consumer = new ConsumeInteger( sharedObject ); 16 // start threads producer.start(); consumer.start(); } 21 22 } // end class SharedCell

55 ProduceInteger setting sharedInt to 1
ConsumeInteger retrieving sharedInt value 1 ProduceInteger setting sharedInt to 2 ConsumeInteger retrieving sharedInt value 2 ProduceInteger setting sharedInt to 3 ConsumeInteger retrieving sharedInt value 3 ProduceInteger setting sharedInt to 4 ConsumeInteger retrieving sharedInt value 4 ProduceInteger setting sharedInt to 5 ConsumeInteger retrieving sharedInt value 5 ProduceInteger setting sharedInt to 6 ConsumeInteger retrieving sharedInt value 6 ProduceInteger setting sharedInt to 7 ConsumeInteger retrieving sharedInt value 7 ProduceInteger setting sharedInt to 8 ConsumeInteger retrieving sharedInt value 8 ProduceInteger setting sharedInt to 9 ConsumeInteger retrieving sharedInt value 9 ProduceInteger setting sharedInt to 10 ProduceInteger finished producing values Terminating ProduceInteger ConsumeInteger retrieving sharedInt value 10 ConsumeInteger retrieved values totaling: 55 Terminating ConsumeInteger


Download ppt "MultiThreading Programming"

Similar presentations


Ads by Google