8.1 Thread
It is 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.
Threading distinguishes Java from C++, and is the ability to have multiple "simultaneous" lines of execution running in a single program. If you are still stuck with a computer that has only one CPU, it's a myth that separate threads run simultaneously. Because they are sharing the cycles of the one CPU, each thread is given a priority—which is number from 1-10 ( 5 is the default priority.) Threads with a higher priority number are given more turns at the CPU. In fact, depending on the operating system, a thread's priority can have a more drastic impact.
Depending on the OS, one of either two strategic is used:
• preemption or
• time slicing:
Under Sun's 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 a thread of higher priority arrives and steals the processor from a lower-priority thread, this is known as preemption. One weakness of the preemption system is this: if another thread of the same priority is waiting to run, it is shut out of the processor. This is called thread starvation.
Another system is used in the windows world. In a process known as time slicing, each thread is given a period of time to run, and then all the other threads of equal priority get their turn at the CPU. As with the preemption system, under time slicing, a higher-priority thread still commandeers the CPU immediately.
8.2 Class Thread: an Overview
java.lang.Thread
When we wish to make a Java program use threading, the easiest way is to say our class extends the class Thread. The Java class Thread has 7 different constructors.
1. Thread()—this constructor takes no arguments.
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.
To instantiate a Thread using this default Constructor, we would do like this:
Thread t1 = new Thread() ;
t1 would have The thread name of Thread-0l
2.Thread (String name)
This Constructor takes a String argument, which becomes the thread's name.
String n = "cece" ;
Thread t2 = new Threas (n);
t2 would have the thread name of cece.
Similarly,
String n = "cece" ;
Thread t3 = new Thread (n);
Thread t4 = new Thread
t3 would have the thread name of cece.
t4 would have the thread name of Thread-0.
(These are 5 more constructors with more ambitious intention. For now, these two are sufficient.)
Once we have instantiated a thread object, we'd 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.
As you would expect, we begin by extending the class Thread.
Bublic class MyThread extends Thread
{
}
First, add the constructor method—which names the thread "Thread-x", Now, because it sub-classes Thread, class MyThread is an instance of the thread class. Class Thread contains a method run() that is empty—it does nothing. So, if you want anything to happen in your thread, you need to override the method run().
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") ;
}
Next we build a driver program and put in a method main. When main executes, the JVM places it in a single thread context.
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 ) ;
chuck.start ( ) ;
MyThread dede = new MyThread ("Deirdra") ;
dede.start ( ) ;
MyThread pat = new MyThread ( "Patrick" ) ;
pat. start ( ) ;
}
}
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 doesn't die until the last thread does. By default, a new thread has the same priority as the thread that created it.
Notice what happened here—in our main method, we instantiated our MyThread class. Then, we executed the start() method of our object. We never called the run() method but, 1o and behold, it got called.
So, how many threads did we give life to in that example?
4
main
chuck,
dede,
pat
So, using threads is much like running a road race:
Before running, you must start
1. Understanding the sequence:
My program is running along happily. Without me doing anything, my program is already running a thread—main. (Therefore, your programs have always been running a single thread.)
2. In this context--where a single thread (main) is already running—you're going to execute the following code:
public static void main (String [ ] args ) ;
{
MyThread mt = new MyThread ( ) ;
mt.start ( ) ;
}
Firstly, understand that your goal is to start up a new thread. When you instantiate a new thread object, and then execute its start() method, you are asking the JVM to create new, additional thread to run alongside the thread you created when your original main() method started up.
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.
Although you have a method run() in your MyThread class, don't 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 ru() in your MyThread class?
Answer: you would execute the run() method in the same thread—thead main—that you were already in, not in a new thread.
What will be the output when we execute main() of the following code?
public class MyThread extends Thread
{
public MyThread (String name )
{
super (name) ;
public run ( )
System.out.println (" In run ( ) – Thread=" + Thread, currentThread ( ) ) ;
}
}
public static void main (String [ ] args ) ;
{
MyThread chuck = new MyThread ( "Charlie" ) ;
chuck.start ( ) ;
MyThread dede = new MyThread ("Deirdra") ;
dede.start ( ) ;
MyThread pat = new MyThread ( "Patrick" ) ;
pat. start ( ) ;
}
Answer:
In run()-Thread=Thread[Charlie,5,main]
In run()-Thread=Thread[Deirdra, 5,main]
In run()-Thread=Thread[Patrick, 5,main]
So, pretend you are holding the starter pistol for a road race. You start the threads, but let them do the running. If you try to execute a start() method on a thread that has already been started, the start() method throws an
IllegalThreadStateException
8.3 Static Thread Methods
Many thread methods are static : A static method belongs to the class—not to any one instance of the class. Therefore, you can execute a static method even if you haven't instantiated the class—such as the case of main.
8.3.1 Static void sleep ( long millisecs)
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.
8.3.2 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() ;
8.3.3 Static void yield()
Causes the currently executing thread object to temporarily pause allow other threads of equal priority to execute.
You would use the method yield() only if your operating system did not support preemptive multithreading.
8.3.4 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. This particular method can be easily confused with another method similarly named. The emphasis here is on CURRENT THREAD. For this method, we don't get to choose the thread we wish to test. By default, it tests whether or not the current thread is interrupted.
8.3.5 Boolean is interrupted ()
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.
8.3.6 void interrupt()
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. This doesn't ask a question, it performs an action
8.4 void wait ()
The thread itself calls the wait() method to wait for a specific condition to be satisfied.
8.4.2 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.
8..2 String getName()
It returns the thread name for the thread.
8.4.4 static void dumStack()
It causes a dump of the execution stack at this instant.
public class MyThread extends Thread
public MyThread (String n ) )
{
super (n) ;
System.out.println ("MyThread Constructor" ) ;
}
}
public class TestMyThread
{
public static void main (String [ ] args ) ;
{
MyThread pat = new MyThread ( ) ;
pat.start ( ) ;
Thread.dumpStack ( ) ;
}
}
We start off with our typical class MyTherad that extends Thread. We then instantiate a thread object, and execute the start() method. Now, because the thread method dumpStack() is static, we call it on the class object.
MyTherad Constructor
java.lang.Exception: stack trace
java.lang.Throwable(java.lang.String)
java.lang.Exception (java.lang.String)
void java.lang.Thread.dumpStack ()
void TestMyThread.main (java.lang.String [ ] )
After dumpStack()
You see main() was the first thing executed. You read a stack dump from the bottom up, the way it was stacked. Next, Thread's static method dumpStack () was called. Finally Exception was called, followed by Throwable, the Superclass.
8.4.5 final void stepriority (int p)
This method allows you the change the priority to an integer between I and 10.
8.4.6 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.
8.5 Thread states
Life Cycle of a Thread:
• born- Thread is instantiated. When start() method is called, thread enters ready state.
• ready- Highest priority thread that is read enters running state.
• runnig-System assigns a processor to the thread and the thread begins to excute its run() method. When run() method completes or terminates, thread enters dead state.
• dead-Thread marked to be removed from the system. Entered when run() terminates or throws uncaught exception.
• 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 a blocked state-waiting on a request for file I/O
• sleeping-Entered when sleep() method has been called for a thread. while in the sleep state, a thread cannot use the processor. After its sleep time expires, the thread re-enters the ready state. It doesn't staring running again. it becomes eligible to run—much in the same way it did when you called the start() method.
• 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 notify All() has been called—all waiting threads become ready.
A thread executes until:
• it dies,
• it calls sleep ().
• it calls yield().
• its quantum of time is used up, or
• it is preempted by higher priority thread.
When a thread has just been instantiated, your only option is to start () it. If you try to execute any method besides start(), you will cause an IllegalThreadStateException
When the Start() method is returns the thread is ready to be run when the scheduler decides it's the right time. Notice on the right there is the state called "not runnable." There are several reasons why a thread that has not finished its run() method could find itself "not runnable." :
• If a thread has been put to sleep, then the sleep milliseconds must elapse.
• If thread is waiting for something, then another object must notify the waiting thread of a change in condition. The other object would handle the notification by calling the methods notify() or notify All().
• If a thread is blocked on I/O, then the I/O must complete.
Let's make sure we have that sequence straight:
• Thread Zelda is waiting for something else.
• Because it cannot go on without the something it's waiting for, Zelda calls the method wait() on itself: Zelda.wait():
• Thread Zelda remains in waiting state until the object it is waiting say scott, announces it is ready by issuing the notify() or notify All()method.
8.6 Thread Synchronization
Until this point, all of our threads have lived alone. However, it's possible to have threads share information. 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?
Coping with this problem raises the thorny subject of thread synchronization.
Public synchronized int getBalance()
{
…
}
The first piece of the puzzle is a thing called a monitor. When we say an object is a monitor, we are merely saying that object has the ability to pay attention to the behavior of threads. We accomplish thread synchronization by making methods synchronized. Further, we say every object that contains synchronized threads is in effect a monitor. So in sumMaya, if an object is a monitor, then that object permits only one thread at a time to execute a synchronized method on that object.
This is implemented as follows:
• Whenever a Synchronized method is invoked, the object is locked.
• If my object has a Synchronized method, and something call 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.
public class LockBox
{
private int contents;
private Boolean available = false;
public synchronized int get ( )
{
return contents;
}
public synchronized void put (int value)
{
contents = value;
}
}
Note that method get() and put() are each synchronized. If my class were calling the put() method, then nobody could call either the put() or the off for everybody until I'm done. Because the class LockBox contains a synchronized method, every instance of class LockBox would have a special lock associated with it.
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.
In other words, if an object has more than one synchronized method, then only one of those synchronized methods at a time can be executing. Synchronized methods are like having a single bathroom—no matter how many need it, can only you by used by one person—boy or girl—at 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. If a synchronized method gets its turn to execute but then—during that execution—it finds it cannot proceed (maybe I/O is blocked or there's some other hold up)—then the thread may voluntarily call its method wait(), In the wait() state, the thread doesn't take up processor resources and doesn't hold a lock on the monitor.
When thread executing synchronized method completes, the thread can execute the notify() method. Executing the notify() method tells any waiting threads to become ready so the scheduler can get them back running again. The notify() method is like calling:
"Head up, you're on deck."
After a thread has been notified, it can attempt to get a lock on the object. Similarly, if a synchronized method no longer need its lock for some reason, it can call notifyAll(), which alerts all waiting threads that they are free to enter the ready mode and again attempt to get a lock on the object.
Warning: if a thread is waiting, it many wait forever—in a state called deadlock—unless 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!
When an object is a monitor, that means it keeps a list of all threads that wish to execute synchronized methods. Just as a method alone can be synchronized, it is possible to just place curly brackets around a chunk of code with the keyword this as an argument. That means, while the tiny block of code so isolated is executing, the object referred to by the this is locked.
Be Careful: synchronization should be used like a spice, not a gravy. It's overuse can spoil your application and slow it way down
It is 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.
Threading distinguishes Java from C++, and is the ability to have multiple "simultaneous" lines of execution running in a single program. If you are still stuck with a computer that has only one CPU, it's a myth that separate threads run simultaneously. Because they are sharing the cycles of the one CPU, each thread is given a priority—which is number from 1-10 ( 5 is the default priority.) Threads with a higher priority number are given more turns at the CPU. In fact, depending on the operating system, a thread's priority can have a more drastic impact.
Depending on the OS, one of either two strategic is used:
• preemption or
• time slicing:
Under Sun's 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 a thread of higher priority arrives and steals the processor from a lower-priority thread, this is known as preemption. One weakness of the preemption system is this: if another thread of the same priority is waiting to run, it is shut out of the processor. This is called thread starvation.
Another system is used in the windows world. In a process known as time slicing, each thread is given a period of time to run, and then all the other threads of equal priority get their turn at the CPU. As with the preemption system, under time slicing, a higher-priority thread still commandeers the CPU immediately.
8.2 Class Thread: an Overview
java.lang.Thread
When we wish to make a Java program use threading, the easiest way is to say our class extends the class Thread. The Java class Thread has 7 different constructors.
1. Thread()—this constructor takes no arguments.
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.
To instantiate a Thread using this default Constructor, we would do like this:
Thread t1 = new Thread() ;
t1 would have The thread name of Thread-0l
2.Thread (String name)
This Constructor takes a String argument, which becomes the thread's name.
String n = "cece" ;
Thread t2 = new Threas (n);
t2 would have the thread name of cece.
Similarly,
String n = "cece" ;
Thread t3 = new Thread (n);
Thread t4 = new Thread
t3 would have the thread name of cece.
t4 would have the thread name of Thread-0.
(These are 5 more constructors with more ambitious intention. For now, these two are sufficient.)
Once we have instantiated a thread object, we'd 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.
As you would expect, we begin by extending the class Thread.
Bublic class MyThread extends Thread
{
}
First, add the constructor method—which names the thread "Thread-x", Now, because it sub-classes Thread, class MyThread is an instance of the thread class. Class Thread contains a method run() that is empty—it does nothing. So, if you want anything to happen in your thread, you need to override the method run().
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") ;
}
Next we build a driver program and put in a method main. When main executes, the JVM places it in a single thread context.
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 ) ;
chuck.start ( ) ;
MyThread dede = new MyThread ("Deirdra") ;
dede.start ( ) ;
MyThread pat = new MyThread ( "Patrick" ) ;
pat. start ( ) ;
}
}
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 doesn't die until the last thread does. By default, a new thread has the same priority as the thread that created it.
Notice what happened here—in our main method, we instantiated our MyThread class. Then, we executed the start() method of our object. We never called the run() method but, 1o and behold, it got called.
So, how many threads did we give life to in that example?
4
main
chuck,
dede,
pat
So, using threads is much like running a road race:
Before running, you must start
1. Understanding the sequence:
My program is running along happily. Without me doing anything, my program is already running a thread—main. (Therefore, your programs have always been running a single thread.)
2. In this context--where a single thread (main) is already running—you're going to execute the following code:
public static void main (String [ ] args ) ;
{
MyThread mt = new MyThread ( ) ;
mt.start ( ) ;
}
Firstly, understand that your goal is to start up a new thread. When you instantiate a new thread object, and then execute its start() method, you are asking the JVM to create new, additional thread to run alongside the thread you created when your original main() method started up.
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.
Although you have a method run() in your MyThread class, don't 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 ru() in your MyThread class?
Answer: you would execute the run() method in the same thread—thead main—that you were already in, not in a new thread.
What will be the output when we execute main() of the following code?
public class MyThread extends Thread
{
public MyThread (String name )
{
super (name) ;
public run ( )
System.out.println (" In run ( ) – Thread=" + Thread, currentThread ( ) ) ;
}
}
public static void main (String [ ] args ) ;
{
MyThread chuck = new MyThread ( "Charlie" ) ;
chuck.start ( ) ;
MyThread dede = new MyThread ("Deirdra") ;
dede.start ( ) ;
MyThread pat = new MyThread ( "Patrick" ) ;
pat. start ( ) ;
}
Answer:
In run()-Thread=Thread[Charlie,5,main]
In run()-Thread=Thread[Deirdra, 5,main]
In run()-Thread=Thread[Patrick, 5,main]
So, pretend you are holding the starter pistol for a road race. You start the threads, but let them do the running. If you try to execute a start() method on a thread that has already been started, the start() method throws an
IllegalThreadStateException
8.3 Static Thread Methods
Many thread methods are static : A static method belongs to the class—not to any one instance of the class. Therefore, you can execute a static method even if you haven't instantiated the class—such as the case of main.
8.3.1 Static void sleep ( long millisecs)
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.
8.3.2 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() ;
8.3.3 Static void yield()
Causes the currently executing thread object to temporarily pause allow other threads of equal priority to execute.
You would use the method yield() only if your operating system did not support preemptive multithreading.
8.3.4 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. This particular method can be easily confused with another method similarly named. The emphasis here is on CURRENT THREAD. For this method, we don't get to choose the thread we wish to test. By default, it tests whether or not the current thread is interrupted.
8.3.5 Boolean is interrupted ()
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.
8.3.6 void interrupt()
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. This doesn't ask a question, it performs an action
8.4 void wait ()
The thread itself calls the wait() method to wait for a specific condition to be satisfied.
8.4.2 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.
8..2 String getName()
It returns the thread name for the thread.
8.4.4 static void dumStack()
It causes a dump of the execution stack at this instant.
public class MyThread extends Thread
public MyThread (String n ) )
{
super (n) ;
System.out.println ("MyThread Constructor" ) ;
}
}
public class TestMyThread
{
public static void main (String [ ] args ) ;
{
MyThread pat = new MyThread ( ) ;
pat.start ( ) ;
Thread.dumpStack ( ) ;
}
}
We start off with our typical class MyTherad that extends Thread. We then instantiate a thread object, and execute the start() method. Now, because the thread method dumpStack() is static, we call it on the class object.
MyTherad Constructor
java.lang.Exception: stack trace
java.lang.Throwable(java.lang.String)
java.lang.Exception (java.lang.String)
void java.lang.Thread.dumpStack ()
void TestMyThread.main (java.lang.String [ ] )
After dumpStack()
You see main() was the first thing executed. You read a stack dump from the bottom up, the way it was stacked. Next, Thread's static method dumpStack () was called. Finally Exception was called, followed by Throwable, the Superclass.
8.4.5 final void stepriority (int p)
This method allows you the change the priority to an integer between I and 10.
8.4.6 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.
8.5 Thread states
Life Cycle of a Thread:
• born- Thread is instantiated. When start() method is called, thread enters ready state.
• ready- Highest priority thread that is read enters running state.
• runnig-System assigns a processor to the thread and the thread begins to excute its run() method. When run() method completes or terminates, thread enters dead state.
• dead-Thread marked to be removed from the system. Entered when run() terminates or throws uncaught exception.
• 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 a blocked state-waiting on a request for file I/O
• sleeping-Entered when sleep() method has been called for a thread. while in the sleep state, a thread cannot use the processor. After its sleep time expires, the thread re-enters the ready state. It doesn't staring running again. it becomes eligible to run—much in the same way it did when you called the start() method.
• 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 notify All() has been called—all waiting threads become ready.
A thread executes until:
• it dies,
• it calls sleep ().
• it calls yield().
• its quantum of time is used up, or
• it is preempted by higher priority thread.
When a thread has just been instantiated, your only option is to start () it. If you try to execute any method besides start(), you will cause an IllegalThreadStateException
When the Start() method is returns the thread is ready to be run when the scheduler decides it's the right time. Notice on the right there is the state called "not runnable." There are several reasons why a thread that has not finished its run() method could find itself "not runnable." :
• If a thread has been put to sleep, then the sleep milliseconds must elapse.
• If thread is waiting for something, then another object must notify the waiting thread of a change in condition. The other object would handle the notification by calling the methods notify() or notify All().
• If a thread is blocked on I/O, then the I/O must complete.
Let's make sure we have that sequence straight:
• Thread Zelda is waiting for something else.
• Because it cannot go on without the something it's waiting for, Zelda calls the method wait() on itself: Zelda.wait():
• Thread Zelda remains in waiting state until the object it is waiting say scott, announces it is ready by issuing the notify() or notify All()method.
8.6 Thread Synchronization
Until this point, all of our threads have lived alone. However, it's possible to have threads share information. 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?
Coping with this problem raises the thorny subject of thread synchronization.
Public synchronized int getBalance()
{
…
}
The first piece of the puzzle is a thing called a monitor. When we say an object is a monitor, we are merely saying that object has the ability to pay attention to the behavior of threads. We accomplish thread synchronization by making methods synchronized. Further, we say every object that contains synchronized threads is in effect a monitor. So in sumMaya, if an object is a monitor, then that object permits only one thread at a time to execute a synchronized method on that object.
This is implemented as follows:
• Whenever a Synchronized method is invoked, the object is locked.
• If my object has a Synchronized method, and something call 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.
public class LockBox
{
private int contents;
private Boolean available = false;
public synchronized int get ( )
{
return contents;
}
public synchronized void put (int value)
{
contents = value;
}
}
Note that method get() and put() are each synchronized. If my class were calling the put() method, then nobody could call either the put() or the off for everybody until I'm done. Because the class LockBox contains a synchronized method, every instance of class LockBox would have a special lock associated with it.
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.
In other words, if an object has more than one synchronized method, then only one of those synchronized methods at a time can be executing. Synchronized methods are like having a single bathroom—no matter how many need it, can only you by used by one person—boy or girl—at 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. If a synchronized method gets its turn to execute but then—during that execution—it finds it cannot proceed (maybe I/O is blocked or there's some other hold up)—then the thread may voluntarily call its method wait(), In the wait() state, the thread doesn't take up processor resources and doesn't hold a lock on the monitor.
When thread executing synchronized method completes, the thread can execute the notify() method. Executing the notify() method tells any waiting threads to become ready so the scheduler can get them back running again. The notify() method is like calling:
"Head up, you're on deck."
After a thread has been notified, it can attempt to get a lock on the object. Similarly, if a synchronized method no longer need its lock for some reason, it can call notifyAll(), which alerts all waiting threads that they are free to enter the ready mode and again attempt to get a lock on the object.
Warning: if a thread is waiting, it many wait forever—in a state called deadlock—unless 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!
When an object is a monitor, that means it keeps a list of all threads that wish to execute synchronized methods. Just as a method alone can be synchronized, it is possible to just place curly brackets around a chunk of code with the keyword this as an argument. That means, while the tiny block of code so isolated is executing, the object referred to by the this is locked.
Be Careful: synchronization should be used like a spice, not a gravy. It's overuse can spoil your application and slow it way down