concurrent programming
DESCRIPTION
Concurrent Programming. Course objective. Introduction to Thread and MultiThread Creating & Managing Threads Life Cycle of a Thread Thread class methods Daemon Threads Thread scheduling & priorities Thread Synchronization Thread Interaction Thread Deadlock Runnable Interface. - PowerPoint PPT PresentationTRANSCRIPT
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Concurrent Programming
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Course objective
• Introduction to Thread and MultiThread• Creating & Managing Threads• Life Cycle of a Thread• Thread class methods• Daemon Threads• Thread scheduling & priorities• Thread Synchronization• Thread Interaction• Thread Deadlock• Runnable Interface
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Learning Approach
The following are strongly suggested for a better learning and understanding of this course: Noting down the key concepts in the class Analyze all the examples / code snippets provided Study and understand the self study topics Completion and submission of all the assignments, on time Completion of the self review questions in the lab guide Study and understand all the artifacts including the reference
materials / e-learning / supplementary materials specified Completion of the project (if application for this course) on time
inclusive of individual and group activities Taking part in the self assessment activities Participation in the doubt clearing sessions
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Introduction to Thread and MultiThread
Session 1
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Introduction to Thread and MultiThread• A thread is the smallest unit of executable code that performs a particular
task.• Java supports multithreading.• An application can contain multiple threads. Each thread is specified a
particular task which is executed concurrently with the other threads. This capability of working with multiple threads is called Multithreading.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Processes and Threads
A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space.
Most implementations of the Java virtual machine run as a single process. Multiprocess applications are beyond the scope of this lesson.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Processes and Threads
Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.
Threads exist within a process — every process has at least one.
Multithreaded execution is an essential feature of the Java platform. Every application has at least one thread
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing ThreadsSession 2
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing Threads
• When you execute your Java programs, there is already one thread that is running and it is the main thread. This main thread is important for two reasons:o It is the thread from which child threads will be created.o It is the last thread to finish execution. The moment the
main thread stops executing, the program is terminated.• Though this main thread is created
automatically with the program execution, it can be controlled through a thread object (Thread).
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing Threads (cont.)• You can work with threads in two ways:
o Declare the class to be a sub-class of Class Thread where you need to override the run method of Class Thread.
class MyThread extends Thread { public void run( ) { //your thread implementation here... }}
o Declare the class that implements Runnable. Then define the run( ) method.
class MyThread implements Runnable { public void run( ) { //your thread implementation here... }}
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing Threads (cont.)• In the Thread subclass, implement the run() method. The signature of
run() must be right. run() is the entry point or starting point (or main) of your thread.
• To start a thread, create an object from your Thread class. Send the "start()" method to the thread object. This will create the new thread, start it as an active entity in your program, and call the run() method in the thread object. Do not call the run() method directly.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing Threads (cont.)• First, have your class implement the Runnable interface, which
has one method, run(). This run() plays the same role as the run() in the Thread subclass
• Second, create an instance of the Thread class, passing an instance of your class to the constructor.
• Finally, send the thread object the start() method.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing Threads (cont.)
• There are several constructors in the class Thread. Two of which are mentioned here: o public Thread(String threadname)
Constructs a thread with the name as threadnameo public Thread( )
Constructs a thread with the name "Thread" which is concatenated with a digit, such as Thread-1, Thread-2 and so on.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Creating & Managing Threads (cont.)
PracticeModify the code so that it produce one Mom and one Dad
Example: Giving name to a thread:
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Life Cycle of a ThreadSession 3
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Life Cycle of a Thread
new Thread
Running
Dead
start()
run() finishes
Time expiresnotify()
sleep()
Ready
Runnable
Suspended
Not-Runnable
Sleeping Blocked
suspend()
resume()
wait()
yield()Scheduler
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Life Cycle of a Thread A thread that has just created is in a born state. The thread does not
immediately start running after it is created. It waits for its start( ) method to be called, and even then it is in a ready to run state.
This thread enters the running state when the system allocates the processor to the thread.
You can temporarily halt the execution of the thread for a period of time with the help of sleep( ) method. The thread then enters the sleeping state which becomes ready after the sleep time expires. Sleeping threads do not use the processor.
The thread enters the waiting state when a running thread calls wait. The thread again enters a ready state after the call to notify is given by other thread associated with that object.
The thread enters a blocked state when the thread is performing the Input/Output operations and becomes ready when the I/O it is waiting for is completed.
The thread enters a dead state after the complete execution of the run() method or its stop method is called.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread class methodsSession 4
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread class methods enumerate(Thread t) Copies into the specified array every active thread in the current
thread's thread group and its subgroups.
getName() Returns the name of the thread
isAlive() Returns true if the thread is alive. A thread is alive if it has been started and has not yet died.
getPriority() Returns the thread’s priority
setName(String name) Changes the name of this thread to be equal to the argument name.
setPriority(int p) Changes the priority of the thread
join() Waits for the thread to die
isDaemon() Checks if the thread is a daemon thread.
setDaemon(boolean on) Marks this thread as either a daemon thread or a user thread
sleep(long milisecs ) Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
start( ) Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Java Thread Primitive Deprecation• These method are deprecated:
•Thread.suspend()•Thread.resume()•Thread.stop()•Thread.destroy()
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Why is Thread.stop deprecated? Why?
Cause this method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors
that it has locked. If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
So what replace Thread.stop? Many uses of stop() should be replaced by code that simply modifies
some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt() method should be used to interrupt the wait.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Why are Thread.suspend and Thread.resume deprecated?
Why? This method has been deprecated, as it is inherently deadlock-prone. If
the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed.
If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes.
So what should I use instead? As with Thread.stop, the prudent approach is to have the "target
thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Why is Thread.destroy deprecated?
This method was originally designed to destroy this thread without any cleanup. Any monitors it held would have remained locked. However, the method was never implemented. If it were to be implemented, it would be deadlock-prone in much the manner of Thread.suspend().
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread class methods (cont.)• Thread.join() – Waiting for Thread to end [this method is blocked
until the thread is die]o If thread A sends the "join()" method to thread B, then thread A will be "not
runnable" until thread B's run methods ends. At that time thread A becomes runnable.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread class methods (cont.)
• Sleep stateo Thread.sleep causes the current thread to pause
execution for a specified period. o The thread does not lose ownership of any monitors. o After specified period, it will awakens.o This is an efficient means of making processor time
available to the other threads of an application or other applications that might be running on a computer system.
o Using by call sleep(long millis) or sleep(long millis, int nanos)
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
ThreadTester.java01 // ThreadTester.java02 // Multiple threads printing at different intervals.03 04 public class ThreadTester {05 06 public static void main( String [] args )07 {08 // create and name each thread09 PrintThread thread1 = new PrintThread( "thread1" );10 PrintThread thread2 = new PrintThread( "thread2" );11 PrintThread thread3 = new PrintThread( "thread3" );12 13 System.err.println( "Starting threads" );14 15 thread1.start(); // start thread1 and place it in ready state16 thread2.start(); // start thread2 and place it in ready state17 thread3.start(); // start thread3 and place it in ready state18 19 System.err.println( "Threads started, main ends\n" );20 21 } // end main22 23 } // end class ThreadTester24
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
ThreadTester.java25 // class PrintThread controls thread execution 26 class PrintThread extends Thread { 27 private int sleepTime; 28 29 // assign name to thread by calling superclass constructor30 public PrintThread( String name ) 31 {32 super( name );33 34 // pick random sleep time between 0 and 5 seconds35 sleepTime = ( int ) ( Math.random() * 5001 );36 } 37 38 // method run is the code to be executed by new thread 39 public void run() 40 { 41 // put thread to sleep for sleepTime amount of time 42 try { 43 System.err.println( 44 getName() + " going to sleep for " + sleepTime ); 45 46 Thread.sleep( sleepTime ); 47 } 48
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
ThreadTester.java49 // if thread interrupted during sleep, print stack trace50 catch ( InterruptedException exception ) { 51 exception.printStackTrace(); 52 } 53 54 // print thread name 55 System.err.println( getName() + " done sleeping" ); 56 57 } // end method run 58 59 } // end class PrintThread
Output:Starting threadsThreads started, main endsthread1 going to sleep for 1217thread2 going to sleep for 3989thread3 going to sleep for 662thread3 done sleepingthread1 done sleepingthread2 done sleeping
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Daemon Threads• A Java program is terminated only after all the threads die.
There are two types of threads in a Java programo User threadso Daemon threads
• The threads that are created by the Java Virtual Machine on your behalf are called daemon threads.
• Java provides a garbage collector thread that reclaims dynamically allocated memory, that is no longer needed. This thread runs as a low priority thread that may be the only thread left running in the JVM. And since all the other threads have terminated, there is no more work to be done and so the JVM can exit. Therefore, the garbage collection is marked as a daemon thread.
• The thread class has two methods that deal with daemon threads.o public void setDaemon(boolean on)o public boolean isDaemon( )
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SimpleThreads Example The following example brings together some of the
concepts of this section. SimpleThreads consists of two threads. The first is the main thread that every Java application has. The main thread creates a new thread from the Runnable object, MessageLoop, and waits for it to finish. If the MessageLoop thread takes too long to finish, the main thread interrupts it.
The MessageLoop thread prints out a series of messages. If interrupted before it has printed all its messages, the MessageLoop thread prints a message and exits.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SimpleThreads.javapublic class SimpleThreads { //Display a message, preceded by the name of the current thread static void threadMessage(String message) { String threadName = Thread.currentThread().getName(); System.out.format("%s: %s%n", threadName, message); }
private static class MessageLoop implements Runnable { public void run() { String importantInfo[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; try { for (int i = 0; i < importantInfo.length; i++) { Thread.sleep(4000); //Pause for 4 seconds threadMessage(importantInfo[i]); //Print a message } } catch (InterruptedException e) { threadMessage("I wasn't done!"); } } }
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SimpleThreads.java public static void main(String args[]) throws InterruptedException { //Delay, in milliseconds before we interrupt MessageLoop thread. long patience = 10000;
threadMessage("Starting MessageLoop thread"); long startTime = System.currentTimeMillis(); Thread t = new Thread(new MessageLoop()); t.start();
threadMessage("Waiting for MessageLoop thread to finish"); //loop until MessageLoop thread exits while (t.isAlive()) { threadMessage("Still waiting..."); //Wait maximum of 1 second for MessageLoop thread to finish. t.join(1000); if (((System.currentTimeMillis() - startTime) > patience) && t.isAlive())
{ threadMessage("Tired of waiting!"); t.interrupt(); //Shouldn't be long now -- wait indefinitely t.join(); } } threadMessage("Finally!"); }}
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Outputmain: Starting MessageLoop threadmain: Waiting for MessageLoop thread to finishmain: Still waiting...main: Still waiting...main: Still waiting...main: Still waiting...main: Still waiting...Thread-0: Mares eat oatsmain: Still waiting...main: Still waiting...main: Still waiting...main: Still waiting...Thread-0: Does eat oatsmain: Still waiting...main: Tired of waiting!Thread-0: I wasn't done!main: Finally!
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread scheduling & prioritiesSession 5
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread scheduling & priorities• Most of the Java programs work with multiple
threads. • The CPU logical core is capable of running only
one thread at a time. • When there are more that two threads in a
program, that are of equal priority, each thread wants the CPU time and the threads compete with each other to access this resource.
• It is the programmer, or the Java Virtual Machine or the operating system that need to ensure that the CPU is shared between the threads. This is called scheduling of threads.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread scheduling & priorities (cont.)• Every thread in Java has its own priority. This
priority is in the range o Thread.MIN_PRIORITY = 1 o Thread.MAX_PRIORITY = 10
• By default, a thread has a priority of Thread.NORM_PRIORITY, a constant of 5.
• Every new thread that is created, inherits the priority of the thread that creates it.
• The priority of the thread can be adjusted with the method called setPriority(int).
• To get priority, use method getPriority().
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread scheduling & priorities (cont.)• Some Java platforms support the concept of
time slicing. In this, every thread receives a small portion of processor time which is called a quantum. The thread can perform its task during this quantum. After the time period is over, even if the thread has not finished its execution, the thread is given no more time to continue and the next thread of equal priority takes the charge of the processor time. The Java scheduler does this, where all equal high-priority threads are timesliced.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread scheduling & priorities (cont.)
Last thread with highest priority (6) will run first
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread SynchronizationSession 6
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread Synchronization• While working with multiple threads, it may so
happen that more than one thread wants to access the same variable at the same time.
• In that case, we need to allow one thread to finish its task completely and then allow the next thread to execute. This can be attained with the help of the synchronized( ) method. This method tells the system to put a lock around a particular method.
• Every object with a synchronized method is a monitor that lets only one thread at a time to execute. After execution, the lock on the object is released and the next priority thread starts running.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Bugs in multi threads
These bugs are introduced when multiple threads access shared data.
Because they are unpredictable, these bugs can be difficult to detect and fix.
So we should have a example to make clear about these bugs.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Counter.javapublic class Counter { private int c = 0; // Start with 0
public void increment() { c++; // Increase by 1 }
public int value() { return c; }}
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
ThreadInterference.javapublic class ThreadInterference extends Thread {
private Counter counter = new Counter();
static void threadMessage(String message) { String threadName = Thread.currentThread().getName(); System.out.format("%s: %s%n", threadName, message);} @Overridepublic void run() {
try {counter.increment();Thread.sleep(1000); //Simulate we are doing something herethreadMessage("" + counter.value());
} catch (InterruptedException e) {e.printStackTrace();
}}
}
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
ThreadInterferenceExample.javapublic class ThreadInterferenceExample {
public static void main(String[] args) {ThreadInterference test = new ThreadInterference();Thread t1 = new Thread(test);t1.start();
Thread t2 = new Thread(test);t2.start();
}}
Here, we expected that:Thread t1 should start Counter object with 0, then increase to 1.Thread t2 should start after that, increase Counter from 1 to 2.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Actual Output
Thread-2: 2Thread-1: 2
Thread t1 result is lost, overwritten by Thread t2.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
• Java uses monitors for thread synchronization
• The sychronized keywordo Every synchronized method of an object has a
monitoro One thread inside a synchronized method at a
timeo All other threads are blocked until synchronized
method finisheso Next highest priority thread runs when method
finishes
Thread Synchronization (cont.)
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
• Each object instance has a “monitor”:o It is combination of general monitor + a single condition
variable.o Classes are objects (Class class). So each class has a
monitor, too.o Ownership of instance monitor:
synchronized void f() { /* owned */ } void f() {
synchronized (this) { /* owned */ } }
o Ownership of class monitor: static synchronized void f() { /* owned */ } void f() {
synchronized (this.getClass()) {/* owned */ } }
Samemonitor.
Samemonitor.
Thread Synchronization (cont.)
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
ThreadInterference.java (fix bug)public class ThreadInterference extends Thread {
private Counter counter = new Counter();
static void threadMessage(String message) { String threadName = Thread.currentThread().getName(); System.out.format("%s: %s%n", threadName, message);} @Overridepublic void run() {
synchronized (counter) {try {
counter.increment();Thread.sleep(1000); //Simulate we are doing something herethreadMessage("" + counter.value());
} catch (InterruptedException e) {e.printStackTrace();
}}
}}
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Actual Output
Thread-2: 1Thread-1: 2
Result now as now correct as we expected.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Practice: Thread Synchronization
• The bank in our model is actually a computer that performs operations on the account, and the account is stored separately. Each clerk can communicate directly with the bank. We'll be defining four classes that we will use in our program to model banking operations:o A Bank class to represent the bank computer.o An Account class to represent the account at the bank.o A Transaction class to represent a transaction on the account ¡ª a debit or a
credit foro instance.o A Clerk class to represent a bank clerk.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread InteractionSession 7
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
• The java.lang.Object class has three methods wait(), notify(), and notifyAll() that help threads communicate about the status of an event that the threads care about.
• When a thread A encounters a wait() method, it sleeps. Thread A stays in this state till another thread wakes it using a notify() method.
• The thread waiting for a condition should look like synchronized void waitingMethod() { while ( ! condition ) wait(); // Now do what you need to do when condition is true }
• notify - How to Use synchronized void changeMethod() { // Change some value used in a condition test notify(); }
Thread Interactionwait(), notify(), and notifyAll()
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Example1: wait() and notify()
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Example2: wait() and notifyAll() Using notifyAll() When Many Threads May Be Waiting
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Sample: Producer/Consumer Relationship without Synchronization
• Buffero Shared memory region
• Producer threado Generates data to add to buffero Calls wait if consumer has not read previous
message in buffero Writes to empty buffer and calls notify for
consumer• Consumer thread
o Reads data from buffero Calls wait if buffer empty
• Synchronize threads to avoid corrupted data
Producer Consumer
wait()nofity()
shared object
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Buffer.java1 // Buffer.java2 // Buffer interface specifies methods called by
Producer and Consumer.3 4 public interface Buffer {5 public void set( int value ); // place value
into Buffer6 public int get(); // return value from Buffer7 }
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Producer.java1 // Producer.java2 // Producer's run method controls a thread that3 // stores values from 1 to 4 in sharedLocation.4 5 public class Producer extends Thread {6 private Buffer sharedLocation; // reference to shared object7 8 // constructor9 public Producer( Buffer shared )10 {11 super( "Producer" );12 sharedLocation = shared;13 }14 15 // store values from 1 to 4 in sharedLocation16 public void run()17 {18 for ( int count = 1; count <= 4; count++ ) { 19 20 // sleep 0 to 3 seconds, then place value in Buffer21 try {22 Thread.sleep( ( int ) ( Math.random() * 3001 ) );23 sharedLocation.set( count ); 24 }25
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Producer.java26 // if sleeping thread interrupted, print stack trace27 catch ( InterruptedException exception ) {28 exception.printStackTrace();29 }30 31 } // end for32 33 System.err.println( getName() + " done producing." + 34 "\nTerminating " + getName() + ".");35 36 } // end method run37 38 } // end class Producer
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Consumer.java1 // Consumer.java2 // Consumer's run method controls a thread that loops four3 // times and reads a value from sharedLocation each time.4 5 public class Consumer extends Thread { 6 private Buffer sharedLocation; // reference to shared object7 8 // constructor9 public Consumer( Buffer shared )10 {11 super( "Consumer" );12 sharedLocation = shared;13 }14 15 // read sharedLocation's value four times and sum the values16 public void run()17 {18 int sum = 0;19 20 for ( int count = 1; count <= 4; count++ ) {21 22 // sleep 0 to 3 seconds, read value from Buffer and add to sum23 try {24 Thread.sleep( ( int ) ( Math.random() * 3001 ) ); 25 sum += sharedLocation.get();26 }27
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Consumer.java28 // if sleeping thread interrupted, print stack trace29 catch ( InterruptedException exception ) {30 exception.printStackTrace();31 }32 }33 34 System.err.println( getName() + " read values totaling: " + sum
+ 35 ".\nTerminating " + getName() + ".");36 37 } // end method run38 39 } // end class Consumer
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
UnsynchronizedBuffer.java1 // UnsynchronizedBuffer.java2 // UnsynchronizedBuffer represents a single shared integer.3 4 public class UnsynchronizedBuffer implements Buffer {5 private int buffer = -1; // shared by producer and consumer threads6 7 // place value into buffer8 public void set( int value )9 {10 System.err.println( Thread.currentThread().getName() +11 " writes " + value );12 13 buffer = value;14 }15 16 // return value from buffer17 public int get()18 {19 System.err.println( Thread.currentThread().getName() +20 " reads " + buffer );21 22 return buffer; 23 }24 25 } // end class UnsynchronizedBuffer
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest.java1 // SharedBufferTest.java2 // SharedBufferTest creates producer and consumer threads.3 4 public class SharedBufferTest {5 6 public static void main( String [] args )7 {8 // create shared object used by threads9 Buffer sharedLocation = new UnsynchronizedBuffer();10 11 // create producer and consumer objects12 Producer producer = new Producer( sharedLocation );13 Consumer consumer = new Consumer( sharedLocation );14 15 producer.start(); // start producer thread16 consumer.start(); // start consumer thread17 18 } // end main19 20 } // end class SharedCell
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest.javaConsumer reads -1Producer writes 1Consumer reads 1Consumer reads 1Consumer reads 1Consumer read values totaling: 2.Terminating Consumer.Producer writes 2Producer writes 3Producer writes 4Producer done producing.Terminating Producer.
Producer writes 1Producer writes 2Consumer reads 2Producer writes 3Consumer reads 3Producer writes 4Producer done producing.Terminating Producer.Consumer reads 4Consumer reads 4Consumer read values totaling: 13.Terminating Consumer.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest.javaProducer writes 1Consumer reads 1Producer writes 2Consumer reads 2Producer writes 3Consumer reads 3Producer writes 4Producer done producing.Terminating Producer.Consumer reads 4Consumer read values totaling: 10.Terminating Consumer.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Sample: Producer/Consumer Relationship with Synchronization
• Synchronize threads to ensure correct data
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SynchronizedBuffer.java1 // SynchronizedBuffer.java2 // SynchronizedBuffer synchronizes access to a single shared integer.3 4 public class SynchronizedBuffer implements Buffer {5 private int buffer = -1; // shared by producer and consumer threads6 private int occupiedBufferCount = 0; // count of occupied buffers7 8 // place value into buffer9 public synchronized void set( int value )10 {11 // for output purposes, get name of thread that called this method12 String name = Thread.currentThread().getName();13 14 // while there are no empty locations, place thread in waiting state15 while ( occupiedBufferCount == 1 ) {16 17 // output thread information and buffer information, then wait18 try {19 System.err.println( name + " tries to write." );20 displayState( "Buffer full. " + name + " waits." );21 wait();22 }23 24 // if waiting thread interrupted, print stack trace25 catch ( InterruptedException exception ) {26 exception.printStackTrace();27 }
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SynchronizedBuffer.java28 29 } // end while30 31 buffer = value; // set new buffer value32 33 // indicate producer cannot store another value34 // until consumer retrieves current buffer value35 ++occupiedBufferCount;36 37 displayState( name + " writes " + buffer );38 39 notify(); // tell waiting thread to enter ready state40 41 } // end method set; releases lock on SynchronizedBuffer 42 43 // return value from buffer44 public synchronized int get()45 {46 // for output purposes, get name of thread that called this method47 String name = Thread.currentThread().getName();48
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SynchronizedBuffer.java49 // while no data to read, place thread in waiting state50 while ( occupiedBufferCount == 0 ) {51 52 // output thread information and buffer information, then wait53 try {54 System.err.println( name + " tries to read." );55 displayState( "Buffer empty. " + name + " waits." );56 wait();57 }58 59 // if waiting thread interrupted, print stack trace60 catch ( InterruptedException exception ) {61 exception.printStackTrace();62 }63 64 } // end while65 66 // indicate that producer can store another value 67 // because consumer just retrieved buffer value68 --occupiedBufferCount;69 70 displayState( name + " reads " + buffer ); 71 72 notify(); // tell waiting thread to become ready to execute 73 74 return buffer;
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SynchronizedBuffer.java75 76 } // end method get; releases lock on SynchronizedBuffer 77 78 // display current operation and buffer state79 public void displayState( String operation )80 {81 StringBuffer outputLine = new StringBuffer( operation );82 outputLine.setLength( 40 );83 outputLine.append( buffer + "\t\t" + occupiedBufferCount );84 System.err.println( outputLine );85 System.err.println();86 }87 88 } // end class SynchronizedBuffer
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest2.java1 // Fig. 16.10: SharedBufferTest2.java2 // SharedBufferTest2creates producer and consumer threads.3 4 public class SharedBufferTest2 {5 6 public static void main( String [] args )7 {8 // create shared object used by threads; we use a SynchronizedBuffer9 // reference rather than a Buffer reference so we can invoke 10 // SynchronizedBuffer method displayState from main11 SynchronizedBuffer sharedLocation = new SynchronizedBuffer();12 13 // Display column heads for output14 StringBuffer columnHeads = new StringBuffer( "Operation" );15 columnHeads.setLength( 40 );16 columnHeads.append( "Buffer\t\tOccupied Count" );17 System.err.println( columnHeads );18 System.err.println();19 sharedLocation.displayState( "Initial State" );20 21 // create producer and consumer objects22 Producer producer = new Producer( sharedLocation );23 Consumer consumer = new Consumer( sharedLocation );24
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest2.java25 producer.start(); // start producer thread26 consumer.start(); // start consumer thread27 28 } // end main29 30 } // end class SharedBufferTest2
Operation Buffer Occupied CountInitial State -1 0Consumer tries to read.Buffer empty. Consumer waits. -1 0Producer writes 1 1 1Consumer reads 1 1 0Consumer tries to read.Buffer empty. Consumer waits. 1 0Producer writes 2 2 1Consumer reads 2 2 0
Producer writes 3 3 1
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest2.java
Consumer reads 3 3 0Consumer tries to read.Buffer empty. Consumer waits. 3 0Producer writes 4 4 1Consumer reads 4 4 0Producer done producing.Terminating Producer.Consumer read values totaling: 10.Terminating Consumer.
Operation Buffer Occupied CountInitial State -1 0Consumer tries to read.Buffer empty. Consumer waits. -1 0Producer writes 1 1 1Consumer reads 1 1 0
Producer writes 2 2 1
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest2.javaProducer tries to write.Buffer full. Producer waits. 2 1Consumer reads 2 2 0Producer writes 3 3 1Consumer reads 3 3 0
Producer writes 4 4 1Producer done producing.Terminating Producer.Consumer reads 4 4 0Consumer read values totaling: 10.Terminating Consumer.
Operation Buffer Occupied CountInitial State -1 0Producer writes 1 1 1Consumer reads 1 1 0Producer writes 2 2 1
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
SharedBufferTest2.javaConsumer reads 2 2 0Producer writes 3 3 1Consumer reads 3 3 0Producer writes 4 4 1Producer done producing.Terminating Producer.Consumer reads 4 4 0Consumer read values totaling: 10.Terminating Consumer.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Thread DeadlockSession 8
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Deadlock
• Deadlock describes a situation where two or more threads are blocked forever, waiting for each other. Neither can run until it gives up the lock, so they’ll sit there forever and ever and ever.
• When a Java program deadlocks, the deadlocking threads simply wait forever. While other threads might continue running, you will eventually have to kill the program.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Deadlock
Deadlock is difficult to debug for two reasons:In general, it occurs only rarely, when the two
threads time-slice in just the right way.It may involve more than two threads and two
synchronized objects. (That is, deadlock can occur through a more convoluted sequence of events than just described.)
It is often related to business logic.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Deadlock Example
Alphonse and Gaston are friends, and great believers in courtesy. A strict rule of courtesy is that when you bow to a friend, you must remain bowed until your friend has a chance to return the bow. Unfortunately, this rule does not account for the possibility that two friends might bow to each other at the same time. This example application models this possibility:
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Deadlock Examplepublic class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void bow(Friend bower) { System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName()); bower.bowBack(this); } public synchronized void bowBack(Friend bower) { System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName()); } }
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Deadlock Example public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new Runnable() { public void run() { alphonse.bow(gaston); } }).start(); new Thread(new Runnable() { public void run() { gaston.bow(alphonse); } }).start(); }}
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Deadlock output
Alphonse: Gaston has bowed to me!Gaston: Alphonse has bowed to me!
Then, the application stand here, cannot escape this situation. We have only choice to kill this application.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
How to avoid deadlock There is no general solution to avoid deadlocks. However, we can:
Narrow down the synchronization's scope to as small a block as possible.
Try to avoid locking multiple objects if possible.Use a consistent lock order, by which if multiple locks
need to be acquired will be acquired in a particular predefined order.
Maintain a proper documentation about the order, and other locking strategy if used.
Paying attention to your program's locking behavior at design time and defining rules for when and how to acquire multiple locks.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Runnable InterfaceSession 9
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Runnable Interface
• A class cannot extend more than one class
• If you extend Thread class, how come you extend your business classes.
• Implement Runnable for multithreading support
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java1 // RandomCharacters.java2 // Class RandomCharacters demonstrates the Runnable interface3 import java.awt.*;4 import java.awt.event.*;5 import javax.swing.*;6 7 public class RandomCharacters extends JApplet implements ActionListener {8 private String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";9 private final static int SIZE = 3;10 private JLabel outputs[];11 private JCheckBox checkboxes[]; 12 private Thread threads[];13 private boolean suspended[];14 15 // set up GUI and arrays16 public void init()17 {18 outputs = new JLabel[ SIZE ];19 checkboxes = new JCheckBox[ SIZE ];20 threads = new Thread[ SIZE ];21 suspended = new boolean[ SIZE ];22 23 Container container = getContentPane();24 container.setLayout( new GridLayout( SIZE, 2, 5, 5 ) );25
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java26 // create GUI components, register listeners and attach 27 // components to content pane28 for ( int count = 0; count < SIZE; count++ ) {29 outputs[ count ] = new JLabel();30 outputs[ count ].setBackground( Color.GREEN );31 outputs[ count ].setOpaque( true );32 container.add( outputs[ count ] );33 34 checkboxes[ count ] = new JCheckBox( "Suspended" );35 checkboxes[ count ].addActionListener( this );36 container.add( checkboxes[ count ] );37 }38 39 } // end method init40 41 // create and start threads each time start is called (i.e., after 42 // init and when user revists Web page containing this applet)43 public void start()44 {45 for ( int count = 0; count < threads.length; count++ ) {46 47 // create Thread; initialize object that implements Runnable48 threads[ count ] = 49 new Thread( new RunnableObject(), "Thread " + ( count + 1 ) );50 51 threads[ count ].start(); // begin executing Thread52 }
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java53 }54 55 // determine thread location in threads array56 private int getIndex( Thread current )57 {58 for ( int count = 0; count < threads.length; count++ )59 if ( current == threads[ count ] )60 return count;61 62 return -1; 63 }64 65 // called when user switches Web pages; stops all threads66 public synchronized void stop()67 {68 // set references to null to terminate each thread's run method69 for ( int count = 0; count < threads.length; count++ ) 70 threads[ count ] = null;71 72 notifyAll(); // notify all waiting threads, so they can terminate73 }74 75 // handle button events76 public synchronized void actionPerformed( ActionEvent event )77 {
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java78 for ( int count = 0; count < checkboxes.length; count++ ) {79 80 if ( event.getSource() == checkboxes[ count ] ) {81 suspended[ count ] = !suspended[ count ];82 83 // change label color on suspend/resume84 outputs[ count ].setBackground(85 suspended[ count ] ? Color.RED : Color.GREEN );86 87 // if thread resumed, make sure it starts executing88 if ( !suspended[ count ] )89 notifyAll(); 90 91 return;92 }93 }94 95 } // end method actionPerformed96 97 // private inner class that implements Runnable to control threads98 private class RunnableObject implements Runnable {99 100 // place random characters in GUI, variables currentThread and 101 // index are final so can be used in an anonymous inner class102 public void run()103 {
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java104 // get reference to executing thread105 final Thread currentThread = Thread.currentThread();106 107 // determine thread's position in array108 final int index = getIndex( currentThread );109 110 // loop condition determines when thread should stop; loop 111 // terminates when reference threads[ index ] becomes null112 while ( threads[ index ] == currentThread ) {113 114 // sleep from 0 to 1 second115 try {116 Thread.sleep( ( int ) ( Math.random() * 1000 ) );117 118 // determine whether thread should suspend execution;119 // synchronize on RandomCharacters applet object120 synchronized( RandomCharacters.this ) { 121 122 while ( suspended[ index ] && 123 threads[ index ] == currentThread ) { 124 125 // temporarily suspend thread execution126 RandomCharacters.this.wait(); 127 } 128 } // end synchronized statement
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java129 130 } // end try131 132 // if thread interrupted during wait/sleep, print stack trace133 catch ( InterruptedException exception ) {134 exception.printStackTrace();135 }136 137 // display character on corresponding JLabel138 SwingUtilities.invokeLater( 139 new Runnable() {140 141 // pick random character and display it142 public void run() 143 {144 char displayChar = 145 alphabet.charAt( ( int ) ( Math.random() * 26 ) );146 147 outputs[ index ].setText( 148 currentThread.getName() + ": " + displayChar );149 }150 151 } // end inner class152 153 ); // end call to SwingUtilities.invokeLater
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
RandomCharacters.java154 155 } // end while156 157 System.err.println( currentThread.getName() + " terminating" );158 159 } // end method run160 161 } // end private inner class RunnableObject162 163 } // end class RandomCharacters
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Summary • Threads are supported by various components of the Java development
environment and it can be confusing where to look for the features that you need.
• This page summarizes where in the Java environment you can find various classes, methods, and language features that participate in the Java threads story.
• java.lang.Thread o In the Java development environment, threads are objects that derive
from java.lang's Thread class. The Thread class defines and implements Java threads. You can subclass the Thread class to provide your own thread implementations or you can use the Runnable interface.
• java.lang.Runnable o The Java language library also defines the Runnable interface which
allows any arbitrary object to provide the body (the run() method) for a Thread.
• java.lang.Object o The base level class, Object, defines three methods you can use to
synchronize methods around a condition variable: wait(), notify(), and notifyAll().
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3
Q&A
93