Post on 06-May-2015
1
Multi-threadingMulti-threading
U Nyein OoU Nyein Oo
COO/Director(IT)COO/Director(IT)
Myanma Computer Co., LtdMyanma Computer Co., Ltd
IADCS Diploma CourseIADCS Diploma Course
2
What’s a Thread?What’s a Thread?
• A process is an executing program memory allocated by OSusually no memory sharing between processes
• A thread is a single sequential flow of control runs in the address space of a process has its own program counter and its own stack frame
• A thread is a path of execution through a program.• Single threaded programs->one path of execution• Multiple threaded programs -> two or more• Threads run in methods or constructors. The threads go
into the methods and follow their instructions.
1. Introduction1. Introduction
3
Initial Remarks about ThreadsInitial Remarks about Threads
• Cheaper in computing resources and creation , a thread can only act within a single process.
• Java threads are built into the language Threads are "light-weight" processes (unlike UNIX processes), which communicate by a combination of shared memory and message passing.
• Sharing resources between threads is done with synchronization.
• This communication mechanism is employed naturally by Java
• Java threads are based on a locking mechanism using monitors for synchronization
1. Introduction (cont;)1. Introduction (cont;)
4
Some spesific uses for threadsSome spesific uses for threads
• Long initiations (in applets that take a while to initialize)
• Repetitive or timed tasks (animations)
• Asynchronous events (event handling such as a mouse click)
• Multiple Tasks (To do more than one thing at once)
• Java applications and applets are naturally threaded.
1. Introduction (cont;)1. Introduction (cont;)
5
Multitasking vs. MultithreadingMultitasking vs. Multithreading
• Multitasking operating systems run multiple programs simultaneously.
• O.S is reponsible for splitting time the time among the different programs that are running
• Once systems allowed different users to run programs at the same time it was a short step to letting the same user run multiple programs simultaneously.
• Multithreading enables users and programs to accomplish multiple simultaneous tasks.
1. Introduction (cont;)1. Introduction (cont;)
6
Overview of MultitaskingOverview of Multitasking
• Each of programs has at least one thread within it.• Single thread in a single process• Process begins execution at a well-known point.
(i.e main () )• Execution of statements follow a predefined order.• During execution process has access to certain data:
thread’s stack->local variables object references->instance variables class or object references-> static variables
1. Introduction (cont;)1. Introduction (cont;)
7
Processes in a Multitasking Processes in a Multitasking EnvironmentEnvironment
• Data within processes is seperated; separate stack for local variables and data area for objects
1. Introduction (cont;)1. Introduction (cont;)
8
Overview of MultithreadingOverview of Multithreading
• Analogy : thread process
• Multiple thread running within a single instance of JVM multiple processes within an OS
1. Introduction (cont;)1. Introduction (cont;)
9
Properties of Multiple ThreadsProperties of Multiple Threads• Each thread begins execution at a well-defined location.• Code execution from starting location in a predefined
sequence.• Each thread executes code independently of others in the prg.• Also mechanisms of threads that allow cooperation.• The threads appear to have a certain degree of simultaneous
execution.• Access to various types of data• Each thread is separate, so that local variables in the methods
are seperate. • Objects and their instance variables can be shared btw
threads in a Java program.• Static variables are automatically shared .
1. Introduction (cont;)1. Introduction (cont;)
10
Possible Uses for MultithreadingPossible Uses for Multithreading
• In general, you’ll have some part of your programtied to a particular event or resource (and you don’t want to hang up the rest of your program because of that).
• So you create a thread associated with that event or resource and let it run independently of the main program.
• A good example could be a “quit” button– you don’t want to be forced to poll the quit button in every piece of
code you write in your program and yet you want the quit button to be responsive, as if you were checking it regularly.
• In fact, one of the most immediately compelling reasons for multithreading is to produce a responsive user interface.
1. Introduction (cont;)1. Introduction (cont;)
11
2.2. Class Class ThreadThread: : An Overview of the An Overview of the ThreadThread MethodsMethods
• Class Thread constructorspublic 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
12
3. Threaded States: Life Cycle of a 3. Threaded States: Life Cycle of a ThreadThread
• 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
13
3. Thread States: Life Cycle of a 3. Thread States: Life Cycle of a ThreadThread
14
4. Thread Priorities and Thread 4. Thread Priorities and Thread SchedulingScheduling
• Java thread priority– Priority in range 1-10
• Timeslicing– Each thread assigned time on the processor by quantum
– Keeps highest priority threads running
•One can implement threads in two ways:
First, by subclassing the Thread class
Second, by implementing the Runnable interface
The Runnable interface allows you to add threading to a class which cannot conveniently extend Thread.
A class that implements the Runnable interface (including the Thread class itself) must implement the run() method containing the "body" of the thread.
ThreadTester.javaThreadTester.java
//ThreadTester.javapublic class ThreadTester { // create and start threads public static void main( String args[] ) { PrintThread thread1, thread2, thread3, thread4; // create four PrintThread objects thread1 = new PrintThread( "thread1" ); thread2 = new PrintThread( "thread2" ); thread3 = new PrintThread( "thread3" ); thread4 = new PrintThread( "thread4" ); System.err.println( "\nStarting threads" ); // start executing PrintThreads thread1.start(); thread2.start(); thread3.start(); thread4.start(); System.err.println( "Threads started\n" ); } } // end class ThreadTester
Class ThreadTester
creates four PrintThreads and
calls their start methods
ThreadTester.javaThreadTester.java
Lines 33-71Lines 33-71
Lines 38-48Lines 38-48
Lines 51-69Lines 51-69
class PrintThread extends Thread { private int sleepTime; // PrintThread constructor assigns name to thread // by calling superclass Thread constructor public PrintThread( String name ) { super( name ); // sleep between 0 and 5 seconds sleepTime = (int) ( Math.random() * 5000 ); // display name and sleepTime System.err.println( "Name: " + getName() + "; sleep: " + sleepTime ); } // control thread's execution public void run() { // put thread to sleep for a random interval try { System.err.println( getName() + " going to sleep" ); // put thread to sleep Thread.sleep( sleepTime ); }
PrintThread inherits from
Thread so each object of the class can
execute in parallel
Constructor initializes sleepTime to be 0 to 4.999 seconds and
outputs name and value of
sleepTime
Thread run method prints a String
saying the thread is going to sleep and
thread sleeps
// if thread interrupted during sleep, catch exception // and display error message catch ( InterruptedException interruptedException ) { System.err.println( interruptedException.toString() ); } // print thread name System.err.println( getName() + " done sleeping" ); } } // end class PrintThread Thread prints name
when done sleeping
17
5. Thread Synchronization5. Thread Synchronization
• 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
18
6. Producer/Consumer Relationship 6. Producer/Consumer Relationship without without Synchronization 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
ProduceInteger.jProduceInteger.javaava
Line 10Line 10
Lines 15-37Lines 15-37
//ProduceInteger.javapublic class ProduceInteger extends Thread { private HoldIntegerUnsynchronized sharedObject; // 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++ ) { // sleep for a random interval try { Thread.sleep( ( int ) ( Math.random() * 3000 ) ); } // process InterruptedException during sleep catch( InterruptedException exception ) { System.err.println( exception.toString() ); } // call sharedObject method from this // thread of execution sharedObject.setSharedInt( count ); }
Instance variable sharedObject
refers to object shared
Method run loops 10 times, sleeping 0-3 seconds and calling setSharedInt
System.err.println( getName() + " finished producing values" + "\nTerminating " + getName() ); }} // end class ProduceInteger
Thread prints that it finished
ConsumeInteger.jConsumeInteger.javaava
Line 10Line 10
Lines 15-39Lines 15-39
Line 23Line 23
Lines 31-32Lines 31-32
//ConsumeInteger.java public class ConsumeInteger extends Thread { private HoldIntegerUnsynchronized sharedObject; // initialize ConsumerInteger thread object public ConsumeInteger( HoldIntegerUnsynchronized shared ) { super( "ConsumeInteger" ); sharedObject = shared; } // ConsumeInteger thread loops until it receives 10 // from sharedObject's getSharedInt method public void run() { int value, sum = 0; do { // sleep for a random interval try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } // process InterruptedException during sleep catch( InterruptedException exception ) { System.err.println( exception.toString() ); } value = sharedObject.getSharedInt(); sum += value; } while ( value != 10 );
Initializes sharedObject to
refer to object shared
Method run contains a do/while
structure that loops 10 times
Each iteration causes the thread to sleep
0-3 seconds
Call method getSharedInt
and assign to variable sum
System.err.println( getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() ); } } // end class ConsumeInteger
Thread prints that it is done consuming
HoldIntegerUnsynHoldIntegerUnsynchronized.javachronized.java
Line 4Line 4
Lines 7-13Lines 7-13
Lines 16-22Lines 16-22
// HoldIntegerUnsynchronized.java // Definition of class HoldIntegerUnsynchronized. public class HoldIntegerUnsynchronized { private int sharedInt = -1; // unsynchronized method to place value in sharedInt public void setSharedInt( int value ) { System.err.println( Thread.currentThread().getName() + " setting sharedInt to " + value ); sharedInt = value; } // unsynchronized method return sharedInt's value public int getSharedInt() { System.err.println( Thread.currentThread().getName() + " retrieving sharedInt value " + sharedInt ); return sharedInt; } } // end class HoldIntegerUnsynchronized
Instance variable sharedInt is the
shared buffer
Method setSharedInt not synchronized
Method getSharedInt not synchronized
SharedCell.javaSharedCell.java
Lines 6-20Lines 6-20
//SharedCell.java // Show multiple threads modifying shared object. public class SharedCell { // execute application public static void main( String args[] ) { HoldIntegerUnsynchronized sharedObject = new HoldIntegerUnsynchronized(); // create threads ProduceInteger producer = new ProduceInteger( sharedObject ); ConsumeInteger consumer = new ConsumeInteger( sharedObject ); // start threads producer.start(); consumer.start(); } } // end class SharedCell
Method main creates a
ProduceInteger thread and a
ConsumeInteger thread and starts them
23
7. Producer/Consumer Relationship 7. Producer/Consumer Relationship with with Thread Synchronization Thread Synchronization• Synchronize threads to ensure correct data
ProduceInteger.jProduceInteger.javaava
Line 10Line 10
Lines 15-37Lines 15-37
// ProduceInteger.java // Definition of threaded class ProduceInteger public class ProduceInteger extends Thread { private HoldIntegerSynchronized sharedObject; // initialize ProduceInteger thread object public ProduceInteger( HoldIntegerSynchronized 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++ ) { // sleep for a random interval try { Thread.sleep( ( int ) ( Math.random() * 3000 ) ); } // process InterruptedException during sleep catch( InterruptedException exception ) { System.err.println( exception.toString() ); } // call sharedObject method from this // thread of execution sharedObject.setSharedInt( count ); }
Instance variable sharedObject
refers to object shared
Method run loops 10 times, sleeping 0-3 seconds and calling setSharedInt
System.err.println( getName() + " finished producing values" + "\nTerminating " + getName() ); } } // end class ProduceInteger
Thread prints that it finished
// ConsumeInteger.java // Definition of threaded class ConsumeInteger public class ConsumeInteger extends Thread { private HoldIntegerSynchronized sharedObject; // initialize ConsumerInteger thread object public ConsumeInteger( HoldIntegerSynchronized shared ) { super( "ConsumeInteger" ); sharedObject = shared; } // ConsumeInteger thread loops until it receives 10 // from sharedObject's getSharedInt method public void run() { int value, sum = 0; do { // sleep for a random interval try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } // process InterruptedException during sleep catch( InterruptedException exception ) { System.err.println( exception.toString() ); } value = sharedObject.getSharedInt(); sum += value; } while ( value != 10 );
Initializes sharedObject to
refer to object shared
Method run contains a do/while
structure that loops 10 times
Each iteration causes the thread to sleep
0-3 seconds
Call method getSharedInt
and assign to variable sum System.err.println(
getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() ); } } // end class ConsumeInteger Thread prints that it is
done consuming
HoldIntegerSynchHoldIntegerSynchronized.javaronized.java
Line 6Line 6
Line 7Line 7
Lines 12-39Lines 12-39
Line 14Line 14
// HoldIntegerSynchronized.java // Definition of class HoldIntegerSynchronized that // uses thread synchronization to ensure that both // threads access sharedInt at the proper times. public class HoldIntegerSynchronized { private int sharedInt = -1; private boolean writeable = true; // condition variable // 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 // thread that called this method must wait try { wait(); } // process Interrupted exception while thread waiting catch ( InterruptedException exception ) { exception.printStackTrace(); } } System.err.println( Thread.currentThread().getName() + " setting sharedInt to " + value ); // set new sharedInt value sharedInt = value;
Variable sharedInt
represents the shared buffer
Variable writeable is the monitor condition
variable
Method setSharedInt
now synchronized
Check if sharedInt can be
written
HoldIntegerSynchHoldIntegerSynchronized.javaronized.java
Lines 44-70Lines 44-70
Line 46Line 46
writeable = false; // tell a waiting thread to become ready notify(); } // 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 // thread that called this method must wait try { wait(); } // process Interrupted exception while thread waiting catch ( InterruptedException exception ) { exception.printStackTrace(); } } // indicate that producer cant store another value // because a consumer just retrieved sharedInt value writeable = true; // tell a waiting thread to become ready notify(); System.err.println( Thread.currentThread().getName() + " retrieving sharedInt value " + sharedInt );
Method getSharedInt
now synchronized
Check if sharedInt can be
read return sharedInt; } } // end class HoldIntegerSynchronized
SharedCell.javaSharedCell.java
Lines 6-20Lines 6-20
// SharedCell.java // Show multiple threads modifying shared object. public class SharedCell { // execute application public static void main( String args[] ) { HoldIntegerSynchronized sharedObject = new HoldIntegerSynchronized(); // create threads ProduceInteger producer = new ProduceInteger( sharedObject ); ConsumeInteger consumer = new ConsumeInteger( sharedObject ); // start threads producer.start(); consumer.start(); } } // end class SharedCell
Method main creates a
ProduceInteger thread and a
ConsumeInteger thread and starts them
Program OutputProgram Output
ProduceInteger setting sharedInt to 1ConsumeInteger retrieving sharedInt value 1ProduceInteger setting sharedInt to 2ConsumeInteger retrieving sharedInt value 2ProduceInteger setting sharedInt to 3ConsumeInteger retrieving sharedInt value 3ProduceInteger setting sharedInt to 4ConsumeInteger retrieving sharedInt value 4ProduceInteger setting sharedInt to 5ConsumeInteger retrieving sharedInt value 5ProduceInteger setting sharedInt to 6ConsumeInteger retrieving sharedInt value 6ProduceInteger setting sharedInt to 7ConsumeInteger retrieving sharedInt value 7ProduceInteger setting sharedInt to 8ConsumeInteger retrieving sharedInt value 8ProduceInteger setting sharedInt to 9ConsumeInteger retrieving sharedInt value 9ProduceInteger setting sharedInt to 10ProduceInteger finished producing valuesTerminating ProduceIntegerConsumeInteger retrieving sharedInt value 10ConsumeInteger retrieved values totaling: 55Terminating ConsumeInteger
Output of numbers is properly
synchronized
30
8. Producer/Consumer Relationship: 8. Producer/Consumer Relationship: The Circular Buffer The Circular Buffer
• Circular buffer– Multiple memory cells
– Produce item if one or more empty cells
– Consume item if one or more filled cells
UpdateThread.javaUpdateThread.java
Lines 7-24Lines 7-24
Lines 19-22Lines 19-22
// UpdateThread.java // Class for updating JTextArea with output. // Java extension packages import javax.swing.*; public class UpdateThread extends Thread { private JTextArea outputArea; private String messageToOutput; // initialize outputArea and message public UpdateThread( JTextArea output, String message ) { outputArea = output; messageToOutput = message; } // method called to update outputArea public void run() { outputArea.append( messageToOutput ); } } // end class UpdateThread
Class UpdateThread
passed as a parameter to
SwingUtilities method
invokeLater to ensure GUI updates
properly
Method run appends text to outputArea
ProduceInteger.jProduceInteger.javaava
Line 9Line 9
// ProduceInteger.java import javax.swing.*; public class ProduceInteger extends Thread { private HoldIntegerSynchronized sharedObject; private JTextArea outputArea; // initialize ProduceInteger public ProduceInteger( HoldIntegerSynchronized shared, JTextArea output ) { super( "ProduceInteger" ); sharedObject = shared; outputArea = output; } // ProduceInteger thread loops 10 times and calls // sharedObject's setSharedInt method each time public void run() { for ( int count = 1; count <= 10; count++ ) { // sleep for a random interval // Note: Interval shortened purposely to fill buffer try { Thread.sleep( (int) ( Math.random() * 500 ) ); }
Places output in JTextArea outputArea
// process InterruptedException during sleep catch( InterruptedException exception ) { System.err.println( exception.toString() ); } sharedObject.setSharedInt( count ); } // update Swing GUI component SwingUtilities.invokeLater( new UpdateThread( outputArea, "\n" + getName() + " finished producing values" + "\nTerminating " + getName() + "\n" ) ); } } // end class ProduceInteger
SwingUtilities method
invokeLater ensures GUI updates
properly
//ConsumeInteger.java import javax.swing.*; public class ConsumeInteger extends Thread { private HoldIntegerSynchronized sharedObject; private JTextArea outputArea; // initialize ConsumeInteger public ConsumeInteger( HoldIntegerSynchronized shared, JTextArea output ){ super( "ConsumeInteger" ); sharedObject = shared; outputArea = output; }
Places output in JTextArea outputArea
// ConsumeInteger thread loops until it receives 10 // from sharedObject's getSharedInt method public void run() { int value, sum = 0; do { // sleep for a random interval try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } // process InterruptedException during sleep catch( InterruptedException exception ) { System.err.println( exception.toString() ); } value = sharedObject.getSharedInt(); sum += value; } while ( value != 10 ); // update Swing GUI component SwingUtilities.invokeLater( new UpdateThread( outputArea, "\n" + getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() + "\n" ) ); } } // end class ConsumeInteger
SwingUtilities method
invokeLater ensures GUI updates
properly
//SharedCell.java // Show multiple threads modifying shared object. import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; // Java extension packages import javax.swing.*; public class SharedCell extends JFrame { // set up GUI public SharedCell() { super( "Demonstrating Thread Synchronization" ); JTextArea outputArea = new JTextArea( 20, 30 ); getContentPane().add( new JScrollPane( outputArea ) ); setSize( 500, 500 ); show(); // set up threads HoldIntegerSynchronized sharedObject = new HoldIntegerSynchronized( outputArea ); ProduceInteger producer = new ProduceInteger( sharedObject, outputArea ); ConsumeInteger consumer = new ConsumeInteger( sharedObject, outputArea );
Set up threads
Set up GUI
// start threads producer.start(); consumer.start(); } // execute application public static void main( String args[] ) { SharedCell application = new SharedCell(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } } // end class SharedCell
Start threads
Execute application
Program OutputProgram Output
36
9. Daemon Threads9. Daemon Threads• Runs for benefit of other threads
– Do not prevent program from terminating
– Garbage is a daemon thread
• Set daemon thread with method setDaemon
10. 10. RunnableRunnable Interface Interface
• Multithreading in a class that extends a class– A class cannot extend more than one class
– Implements Runnable for multithreading support
• Runnable object grouped with a Thread object
Program – RandomCharacter.java will be shown it