Professional Documents
Culture Documents
Chapter 15
Multithreading
thread
The basic unit of program execution. A process can have several threads running concurrently, each performing a different job. When a thread has finished its job, it is suspended or destroyed.
An Example of Threading
http://java.sun.com/docs/books/tutorial/essential/threads/index.html Java II--Copyright 2001-2002 Tom Hunter
15.1 Introduction
If anyone attempts tell you that C++ is better than Java, you only need to mention one word:
Threading
Java II--Copyright 2001-2002 Tom Hunter
Aside from Java, the language Adaused by the Department of Defenseis the only other language that natively supports multi-threading.*
concurrent
threads of execution
* The language C# (C-pound) has been alleged to support a form of multi-threading.
Java II--Copyright 2001-2002 Tom Hunter
Because they are sharing the cycles of the one CPU, each thread is given a prioritywhich is a number from 1-10. ( 5 is the default priority.)
preemption or
timeslicing.
Under Suns Solaris operating system, a thread of a certain priority is allowed to run until it is finished, or until a thread of higher priority becomes ready to run.
When we wish to make a Java program use threading, the easiest way is to say our class extends the class Thread.
java.lang.Thread
Java II--Copyright 2001-2002 Tom Hunter
1.) Every instantiated thread object has a name. When we use the no-argument Constructor, the names are automatically generated. A thread created using the Constructor above would be named: Thread-0, Thread-1, Thread-2, etc.
Java II--Copyright 2001-2002 Tom Hunter
String n = cece;
(There are 5 more Constructors with more ambitious intentions. For now, these two are sufficient.)
Once we have instantiated a thread object, wed like to put it to work. All of the work done by a thread happens in the method:
run()
This method takes no arguments and returns void. Normally, you will never call the run() method yourself. You will call another method start() and the JVM will call run() when it is good and ready.
Java II--Copyright 2001-2002 Tom Hunter
public class MyThread extends Thread { public MyThread( String n ) { super( n ); System.out.println( MyThread Constructor ); } public void run()
{
System.out.println( In run!\n ); } }
Now, because it sub-classes Thread, class MyThread is an instance of the thread class.
First, add the constructor methodwhich names the thread Thread-x. Class Thread contains a method run() that is emptyit does nothing. So, if you want anything to happen in your thread, you need to override the method run().
Java II--Copyright 2001-2002 Tom Hunter
public class MyThread extends Thread { public MyThread( String n ) { super( n ); System.out.println( MyThread Constructor ); } public void run() { System.out.println( In run!\n ); } public class TestMyThread { public static void main( String[] args ) {
Next we build a driver program and put in a method main. When main executes, the JVM places it in a single thread context.
}
}
Java II--Copyright 2001-2002 Tom Hunter
public class MyThread extends Thread { public MyThread( String n ) { super( n ); System.out.println( MyThread Constructor ); } public void run() { System.out.println( In run!\n ); } So, will we already be public class TestMyThread { public static void main( String[] args ) { MyThread chuck = new MyThread( "Charlie" ); chuck.start(); MyThread dede dede.start(); MyThread pat pat.start(); = new MyThread( Deirdra" ); = new MyThread( Patrick" );
}
}
main() will instantiate and start() all these threads. After they have started, the methods immediately return and the thread main() dies. However the entire application doesnt die until the last thread does.
Java II--Copyright 2001-2002 Tom Hunter
public class MyThread extends Thread chuck=Thread[Charlie,5,main] { dede=Thread[Deirdra,5,main] public MyThread( String n ) pat=Thread[Patrick,5,main] { super( n ); Thread name System.out.println( In Constructor ); priority } public void run() thread groups { System.out.println( In run!\n ); } By default, a new thread has the same } public class TestMyThread priority as the thread that created it. { public static void main( String[] args ) { MyThread chuck = new MyThread( Charles ); chuck.start(); MyThread dede = new MyThread( Deirdra ); dede.start(); MyThread pat = new MyThread( Patrick ); pat.start(); System.out.println( "chuck=" + chuck.toString() ); System.out.println( " dede=" + dede.toString() ); System.out.println( " pat=" + pat.toString() ); } }
Java II--Copyright 2001-2002 Tom Hunter
Notice what happened herein our main method, we instantiated our MyThread class. Then, we executed the start() method of our object. We never called the run() method but, lo and behold, it got called.
So, using threads is much like running a road race: Before running, you must start. 1.) So, lets understand the sequence: My program is running along happily. Without me doing anything, my program is already running in a threadmain. (Therefore, your programs have always been running in a single thread.)
Java II--Copyright 2001-2002 Tom Hunter
2.) In this contextwhere a single thread (main) is already runningyoure going to execute the following code: We say that start()
launches a new thread, and then returns to the calling program, thereby permitting the calling program to continue working independently of the just-launched thread.
public static void main( String[] args ) { MyThread mt = new MyThread(); mt.start(); }
When you instantiate a new thread object, and then execute its start() method, you are asking the JVM to create a new, additional thread to run alongside the thread you created when your original main() method started up.
Java II--Copyright 2001-2002 Tom Hunter
Although you have a method run() in your MyThread class, dont ever execute the run() method yourself. Let the JVM do it for you after you execute the start() method.
public static void main( String[] args ) { MyThread mt = new MyThread(); mt.start(); mt.run(); }
Question: what would happen if you yourself executed the method run() in your MyThread class? Answer: you would execute the run() method in the same thread thread mainthat you were already in, not in a new thread.
Java II--Copyright 2001-2002 Tom Hunter
public class MyThread extends Thread { public MyThread( String name ) { super( name ); }
public static void main( String[] args ) { MyThread chuck = new MyThread( Charlie ); chuck.start();
public class MyThread extends Thread { public MyThread( String name ) { super( name ); } In run()-thread=Thread[Charlie,5,main] public run() { System.out.println( In run()-thread= + Thread.currentThread() ); In run()-thread=Thread[Deirdra,5,main] } } In run()-thread=Thread[main,5,main] In run()-thread=Thread[Patrick,5,main]
public static void main( String[] args ) { MyThread chuck = new MyThread( Charlie ); chuck.start();
MyThread dede dede.start(); = new MyThread( Deirdra );
dede.run();
MyThread pat pat.start(); } = new MyThread( Patrick );
What will be the output NOW when we execute main()? Notice, I added a statement: dede.run();
Java II--Copyright 2001-2002 Tom Hunter
So, pretend you are holding the starter pistol for a road race.
15.2 A Survey of static Thread Methods Many thread methods are static : ( Review: what does it mean when a method is static? )
A static method belongs to the classnot to any one instance of the class. Therefore, you can execute a static method even if you havent instantiated the classsuch as the case of main.
Java II--Copyright 2001-2002 Tom Hunter
Causes the currently executing thread to sleep (meaning temporarily cease execution) for the specified number of milliseconds.
During this sleep time the thread does not use any resources of the processor.
(Good Test Question)
15.2 An Overview of the Thread Methods static Thread currentThread() Returns a reference to the currently executing thread object. In other words, if you want to know which thread is currently executing, you execute this method. and what would be the syntax to do that? Thread x; x = Thread.currentThread();
Java II--Copyright 2001-2002 Tom Hunter
15.2 An Overview of the Thread Methods static void yield() Causes the currently executing thread object to temporarily pause and allow other threads of equal priority to execute. You would use the method yield() only if your operating system did not support preemptive multithreading.
Attention! The static thread methods have one thing in common: they all operate on the
current thread.
Java II--Copyright 2001-2002 Tom Hunter
boolean isInterrupted()
Interrupt this thread !
void interrupt()
Java II--Copyright 2001-2002 Tom Hunter
15.2 A Survey of the Thread Methods static boolean interrupted() True or False.
Tests whether or not the current thread has been interrupted recently.
This static method discovers whether or not the current thread has been interrupted.
Calling this method also resets the interrupted status of its argument.
Java II--Copyright 2001-2002 Tom Hunter
15.2 A Survey of the Thread Methods static boolean interrupted() This particular method can be easily confused with another method similarly named. The emphasis here is on CURRENT THREAD.
For this method, we dont get to choose the thread we wish to test. By default, it tests whether or not the current thread is interrupted.
15.2 A Survey of the Thread Methods boolean isInterrupted() Tests whether or not THIS thread has been interrupted. This method can be used to discover whether any thread has been interrupted. Also, calling this method does NOT change the interrupted status of its argument.
Interrupts this thread. If called on a thread object that is already currently blocked, the blocking call (such as sleep() or wait() complains about the interrupt() call and terminates with an InterruptedException. Sends an interrupt message to a thread. The interrupted status of the thread is set to true.
Java II--Copyright 2001-2002 Tom Hunter
15.2 A Survey of the Thread Methods void wait() The thread itself calls the wait() method to wait for a specific condition to be satisfied.
15.2 A Survey of the Thread Methods boolean isAlive() returns true if: start() has been called for the thread, and the thread is not yet dead, meaning the run() method has not yet finished and died.
Java II--Copyright 2001-2002 Tom Hunter
15.2 A Survey of the Thread Methods String getName() returns the thread name for the thread. dont mistake this for the reference to the thread.
15.2 A Survey of the Thread Methods void setName( String n ) sets the thread name for the thread.
15.2 A Survey of the Thread Methods static void dumpStack() causes a dump of the execution stack at this instant. this has great potentiallearn how to use it.
public class MyThread extends Thread { public MyThread() { System.out.println( MyThread Constructor ); } }
We start off with our typical class MyThread that extends Thread.
public class MyThread extends Thread { public MyThread( String n ) { super( n ); System.out.println( MyThread Constructor ); } We instantiate }
public class TestMyThread { public static void main( String[] args ) { MyThread pat = new MyThread(); pat.start(); Thread.dumpStack(); Now, because the thread } method dumpStack() is }
Next, Threads static method dumpStack() was called. You see main() was the first thing executed.
You read a stack dump from the bottom up, the way it was stacked.
Java II--Copyright 2001-2002 Tom Hunter
15.2 A Survey of the Thread Methods final void setPriority( int p ) This method allows you the change the priority to an integer between 1 and 10.
15.2 A Survey of the Thread Methods final int getPriority() This method lets you return the priority for a thread.
Notice, this method is final to prevent you from causing any mischief.
born
Thread is Instantiated
ready running
dead
blocked
sleeping
waiting
blocked
To enter blocked state, thread must already have been in running state. Even if the CPU is available, a blocked thread cannot use the processor. Common reason for a thread being in a blocked statewaiting on a request for file I/O .
sleeping
waiting
Entered when wait() method has been called in an object thread is accessing.
One waiting thread becomes ready when object calls the method notify().
When the method notifyAll() has been calledall waiting threads become ready.
A thread executes until: it dies, it calls sleep(), it calls wait(), it calls yield(),
When the start() method is returns the thread is ready to be run when the scheduler decides its the right time.
Java II--Copyright 2001-2002 Tom Hunter
Thread Synchronization
In a class, it is common for many threads to all have access to instance variables that have class scope. However, this usually raises issues that could never arise when threads were not involved.
For example, what happens when two threads try to write to or read from an instance variable at the same instant?
thread synchronization.
Further, we say every object that contains synchronized threads is in effect a monitor.
If an object is a monitor, then that object permits only one thread at a time to execute a synchronized method on that object.
Java II--Copyright 2001-2002 Tom Hunter
object is locked.
in other words: if my object has a synchronized method, and something calls that synchronized method, then my object is locked up tight. In fact, for every Java object that contains a synchronized method, Java creates a lock associated with that object.
Java II--Copyright 2001-2002 Tom Hunter
public class LockBox { private int contents; private boolean available = false; public synchronized int get() { return contents; } public synchronized void put( int value ) { contents = value; } }
If my class were calling the put() method, then nobody could call either the put() or the get() method in that instance. I have locked up that instance and its hands off for everybody until Im done.
Because the class LockBox contains a synchronized method, every instance of class LockBox would have a special lock associated with it.
Java II--Copyright 2001-2002 Tom Hunter
public class LockBox { private int contents; private boolean available = false; public synchronized int get() { return contents; } public synchronized void put( int value ) { contents = value; } }
So, you see: when somebody is putting a value to the contents variable, nobody else can get it until the put is done. Likewise, when somebody is getting the value currently in the contents variable, nobody else can change that value in the middle of the read.
Java II--Copyright 2001-2002 Tom Hunter
Synchronized methods are like having a single bathroom no matter how many need it, it can only be used by one personboy or girlat a time.
When the synchronized method is done executing, it releases the lock. The monitor gives the go ahead to the highest-priority thread that is ready to execute the synchronized method.
Java II--Copyright 2001-2002 Tom Hunter
In the wait() state, the thread doesnt take up processor resources and doesnt hold a lock on the monitor.
After a thread has been notified, it can attempt to get a lock on the object.
Java II--Copyright 2001-2002 Tom Hunter
Warning: if a thread is waiting, it may wait foreverin a state called deadlockunless some other thread notifies it that it can enter the ready state. So, if you ever make something wait() be sure to wake it up!
Java II--Copyright 2001-2002 Tom Hunter
That means, while the tiny block of code so isolated is executing, the object referred to by the this is locked.
Its overuse can spoil your application and slow it way down. Beware!
Say we were selling peaches [without synchronization] i.) Consumer asks me for 35 pounds of peaches. ii.) I Produce the 35 pounds of peaches, weigh them and write down the total bill on a chalk slate. iii.) My partner Luigi bags the peaches, reads the price on the slate and takes the money. iv.) But Im much faster than Luigi, so by the time he gets the peaches bagged, Ive already erased the slate and put the next price down there, which was for 5 pounds of peaches. v.) Result: Consumer pays for 5 pounds of peaches, walks with 35 pounds and Luigi and I go out of business.
Java II--Copyright 2001-2002 Tom Hunter
Say we were selling peaches [ with synchronization ] i.) Consumer asks me for 35 pounds of peaches. ii.) I Produce the 35 pounds of peaches, weigh them and write down the total bill on a chalk slate. iii.) My partner Luigi bags the peaches, reads the price on the slate and takes the money. iv.) Im much faster than Luigi, so Ithe Producercall a wait(). v.) When Luigi is caught up he will notify() me vi.) Result: Consumer gets annoyed because of the delay but we stay in business because our operations are synchronized.
Java II--Copyright 2001-2002 Tom Hunter