Java Thread Programming 1.8.1

  The Need for Inter-thread Signaling 
  Through synchronization, one thread can safely change values that another thread will read. How does the second thread know that the values have changed? What if the second thread is waiting for the values to change by rereading the values every few seconds? 
  One not-so-good way that a thread can wait for a value to change is by using a busy / wait: 
  While (getValue ()! = DesiredValue) ( 
  Thread.sleep (500); 
  ) 
  Such code is called a busy / wait because the thread is busy using up processor resources to continually check to see if the value has changed. To use fewer resources, the sleep time could be increased, but then the thread might not find out about the change for quite some time. On the other hand, if the sleep time is reduced, the thread will find out sooner, but will waste even more of the processor resources. In Java, there is a much better way to handle this kind of situation : the wait / notify mechanism. 
  Sometimes we need to communications between the threads, for example, know how to thread a second thread of a certain value has changed?    Not good method above, as busy / wait, and through continuous cycle with Thread.sleep () value of testing whether there has been a change, will occupy processor resources, and the frequency of recycling is not easy, fast and waste resources, slow reduce the reaction rate.    Like this situation, in the java gives a better solution: wait / notify mechanism 
  The Wait / Notify Mechanism 
  The wait / notify mechanism allows one thread to wait for a notification from another thread that it may proceed. 
  Minimal Wait / Notify 
  At a bare minimum, you need an object to lock on and two threads to implement the wait / notify mechanism. 
  Imagine that there is a member variable, valueLock, that will be used for synchronization: 
  Private Object valueLock = new Object (); 
  The first thread comes along and executes this code fragment: 
  Synchronized (valueLock) ( 
  Try ( 
  ValueLock. Wait (); 
  ) Catch (InterruptedException x) ( 
  System.out.println ( "interrupted while waiting"); 
  ) 
  ) 
  The wait () method requires the calling thread to have previously acquired the object-level lock on the target object. In this case, the object that will be waited upon is valueLock, and two lines before the valueLock.wait () statement is the synchronized (valueLock) statement. The thread that invokes the wait () method releases the object-level lock and goes to sleep until notified or interrupted. If the waiting thread is interrupted, it competes with the other threads to reacquire the object-level lock and throws an InterruptedException from within wait () If the waiting thread is notified, it competes with the other threads to reacquire the object-level lock and then returns from wait (). 
  Wait () method need to be object-level lock only after the call, otherwise they will be dished out IllegalMonitor - 
  StateException anomaly, when thread calls wait () methods, and will release object-level lock, and then sleep (), until they were notified or interrupted, if interrupted, this thread will re-compete for object-level lock, and then dished out InterrruptedException, if notified, the threads will re-compete for object-level lock, wait (), to continue to implement wait () after the code. 
  Many times, a thread is interrupted to signal it that it should clean up and die (see Chapter 5). The statements used to wait can be slightly rearranged to allow the InterruptedException to propagate up further: 
  Try ( 
  Synchronized (valueLock) ( 
  ValueLock. Wait (); 
  ) 
  ) Catch (InterruptedException x) ( 
  System.out.println ( "interrupted while waiting"); 
  / / Clean up, and allow thread to return from run () 
  ) 
  Sometimes, in order to interrupt a thread is the destruction of their removal may be abnormal delay in processing InterruptedException 
  Instead of catching InterruptedException, the methods can simply declare that they throw it to pass the exception further up the call chain: 
  Public void someMethod () throws InterruptedException ( 
  / / … 
  Synchronized (valueLock) ( 
  ValueLock. Wait (); 
  ) 
  / / … 
  ) 
  If we fail to capture unusual method can continue to throw on, left after processing 
  The thread doing the notification comes along and executes this code fragment: 
  Synchronized (valueLock) ( 
  ValueLock. Notify (); / / notifyAll () might be safer … 
  ) 
  This thread blocks until it can get exclusive access to the object-level lock for valueLock. After the lock is acquired, this thread notifies one of the waiting threads. If no threads are waiting, the notification effectively does nothing. If more than one thread is waiting on valueLock, the thread scheduler arbitrarily chooses one to receive the notification. The other waiting threads are not notified and continue to wait. To notify all waiting threads (instead of just one of them), use notifyAll () (discussed later in this chapter). 
  First to get object-level lock, and then call notify () notice of this object-level lock all waiting for a thread, if there is no waiting threads, the notice invalid.    If there is more than waiting for the thread, the thread call notification mechanism select one of these, the other not to wait for further notice.    If all of this to inform the locked waiting threads, apply notifyAll () 
  Typical Wait / Notify 
  In most cases, a member variable is checked by the thread doing the waiting and modified by the thread doing the notification. The checking and modification occur inside the synchronized blocks to be sure that no race conditions develop. 
  In most cases, are waiting for a thread of a member variable to meet a condition, and the other members of variables to amend this thread after notification. 
  This time, two member variables are used: 
  Private boolean value = false; 
  Private Object valueLock = new Object (); 
  The value variable is checked by the thread doing the waiting and is set by the thread doing the notification. Synchronization on valueLock controls concurrent access to value. 
  The first thread comes along and executes this code fragment: 
  Try ( 
  Synchronized (valueLock) ( 
  While (value! = True) ( 
  ValueLock.wait (); 
  ) 
  / / Value is now true 
  ) 
  ) Catch (InterruptedException x) ( 
  System.out.println ( "interrupted while waiting"); 
  ) 
  After acquiring the object-level lock for valueLock, the first thread checks value to see if it is true. If it is not, the thread executes wait (), releasing the object-level lock. When this thread is notified, it wakes up , reacquires the lock, and returns from wait (). To be sure that it was not falsely notified (see the "Early Notification" discussion later in this chapter), it re-evaluates the while expression. If value is still not true, the thread waits again. If it is true, the thread continues to execute the rest of the code inside the synchronized block. 
  While the first thread is waiting, a second thread comes along and executes this code fragment: 
  Synchronized (valueLock) ( 
  Value = true; 
  ValueLock.notify (); / / notifyAll () might be safer … 
  ) 
  When the first thread executes the wait () method on valueLock, it releases the object-level lock it was holding. This release allows the second thread to get exclusive access to the object-level lock on valueLock and enter the synchronized block. Inside, the second thread sets value to true and invokes notify () on valueLock to signal one waiting thread that value has been changed. 
  Wait / Notify with synchronized Methods 
  Sometimes, the class is designed to synchronize on this instead of another object. In this case, the synchronized method modifier can be used instead of a synchronized statement. The following code fragments are an adaptation of the previous example. 
  If it is not synchronous other objects, but this synchronization can be combined in the class definition wait / notify mechanism for the use of synchronized method. 
  As before, a member variable value is initially set to false: 
  Private boolean value = false; 
  The first thread (threadA) comes along and invokes this waitUntilTrue () method: 
  Public synchronized void waitUntilTrue () 
  Throws InterruptedException ( 
  While (value == false) ( 
  Wait (); 
  ) 
  ) 
  While threadA is blocked on the wait (), a second thread (threadB) comes along and executes this method, passing in true for newValue: 
  Public synchronized void setValue (boolean newValue) ( 
  If (newValue! = Value) (, 
  Value = newValue; 
  Notify (); / / notifyAll () might be safer … 
  ) 
  ) 
  Note that both methods are synchronized and are members of the same class. In addition, both threads are invoking methods on the same instance of this class. The waitUntilTrue () method (with the wait () inside) declares that it might throw an InterruptedException . In this case, when threadB passes in true, the value is changed and notify () is used to signal the waiting threadA that it may proceed. threadA wakes up, reacquires the object-level lock on this, the returns from wait (), and re-evaluates the while expression. This time, the value is true, and threadA will return from waitUntilTrue (). 
  As mentioned, involved in the definition of wait and notify the two methods have been defined as synchronized, if two threads are calling with such an example, two threads can communicate with each other. 
  Object API Used for Wait / Notify 
  The wait / notify mechanism is embedded deep in the heart of Java. Object, the superclass of all classes, has five methods that are the core of the wait / notify mechanism: notify (), notifyAll (), wait () and wait ( long), and wait (long, int). All classes in Java inherit from Object, so all classes have these public methods available to them. Additionally, none of these methods can be overridden in a subclass as they are all declared final. 
  Java father of all categories of built-in wait Object / notify mechanism, it built wait / notify the five core mechanism: 
  Notify (), notifyAll (), wait () and wait (long), the wait (long, int), the java in all five categories have this method, this method is five public, and final, not quilt category coverage. 
  Notify () 
  Public final native void notify () 
  Throws IllegalMonitorStateException / / RuntimeException 
  The notify () method is used by a thread to signal any other threads that might be waiting on the object. If more than one thread is waiting on the object, the thread scheduler will arbitrarily choose exactly one to be notified, and the others will continue to wait. If no threads are currently waiting on the object, notify () has no effect. Before invoking notify (), a thread must get exclusive access to the object-level lock for the object. Unlike wait (), the invocation of notify () does not temporarily release the lock. If the proper lock is not held when notify () is called, an IllegalMonitorStateException is thrown. This exception is a subclass of RuntimeException, so a try-catch construct is not necessary and is rarely used. 
  Notify () method used to notify the signal for all of the other threads.    If there is more than one thread to wait, will select one of these to notice other continue to wait, if there is no thread to wait, this method is ineffective.    Call notify () do not resemble the wait (), as the release lock, but after the completion of its pending release lock.    If the call notify () is not in possession of appropriate locks, throws IllegalMonitorStateException (RuntimeException sub-categories, not try / catch) 
  NotifyAll () 
  Public final native void notifyAll () 
  Throws IllegalMonitorStateException / / RuntimeException 
  The notifyAll () method works the same as notify () (see above) with one important exception: When notifyAll () is invoked, all the threads waiting on the object are notified, not just one. The advantage of notifyAll () is that you don't have to be concerned about which one of the waiting threads will be notified-they will all be notified. The disadvantage is that it might be wasteful (in terms of processor resources) to notify all the waiting threads if only one will actually be able to proceed. When in doubt, err on the side of safety over speed and use notifyAll () instead of notify (). 
  NotifyAll () to inform all waiting for the locked thread, its obvious shortcomings, if not necessary to notify all waiting threads, may be a waste of processor resources.    Based on safety rather than speed considerations, should be used notifyAll (), rather than notify (). 
  Wait () 
  Public final void wait () 
  Throws InterruptedException, 
  IllegalMonitorStateException / / RuntimeException 
  The wait () method is used to put the current thread to sleep until it is notified or interrupted. Before invoking wait (), a thread must get exclusive access to the object-level lock for the object. Just after entering wait (), the current thread releases the lock. Before returning from wait (), the thread competes with the other threads to reacquire the lock. If the proper lock is not held when wait () is called, an IllegalMonitorStateException is thrown. This exception is a subclass of RuntimeException, so a try-catch construct is not necessary and is rarely used. 
  If the waiting thread is interrupted, it competes to reacquire the lock and throws an InterruptedException from within wait (). This exception is not a subclass of RuntimeException, so a try-catch construct is required. 
  Wait () will be the current thread sleep until they are notified or interrupted. 
  Calling wait (), threads must be exclusive access to the target object-level lock. 
  Entered wati (), the current thread on the release of object-level lock. 
  In the wait () returns, and the other threads to compete for this thread lock. 
  If not in possession of appropriate locks on the call wait () throws IllegalMonitorStateException. 
  If the thread was waiting for interrrupted, this will be re-lock, and then dished out InterrruptedException, this anomaly of non-RuntimeException subclass, it is necessary to try / catch. 
  Wait (long) 
  Public final native void wait (long msTimeout) 
  Throws InterruptedException, 
  IllegalMonitorStateException, / / RuntimeException 
  IllegalArgumentException / / RuntimeException 
  The wait (long) method is used to put the current thread to sleep until it is notified, interrupted, or the specified timeout elapses. Other than the timeout, wait (long) behaves the same as wait () (see above). The argument msTimeout specifies the maximum number of milliseconds that the thread should wait for notification. If msTimeout is 0, the thread will never time out (just like wait ().) If the argument is less than 0, an IllegalArgumentException will be thrown. IllegalArgumentException is a subclass of RuntimeException, so a try-catch block is not required and is rarely used. 
  Thread waiting for a certain period of time, milliseconds, if the parameter is set to 0, no time limit, if the parameter is less than 0, dished out IllegalArgumentException abnormal, unusual for this sub-category RuntimeException, do not try-catch 
  If the specified number of milliseconds elapses before the waiting thread is notified or interrupted, it competes to reacquire the lock and returns from wait (long). There is no way for the caller to determine whether a notification or a timeout occurred because no information ( void) is returned from wait (long). 
  If you set the time was not notified waiting threads / interrupted will be re-lock and then wait ().    There is no way to know call is to be notified or overtime, because wait (long) did not return to duty. 
  Wait (long, int) 
  Public final void wait (long msTimeout, int nanoSec) 
  Throws InterruptedException, 
  IllegalMonitorStateException, / / RuntimeException 
  IllegalArgumentException / / RuntimeException 
  The wait (long, int) method works just like wait (long, int) (see above) with the exception that nanoseconds can be added to the timeout value. The argument nanoSec is added to msTimeout to determine the total amount of time that the thread will wait for notification before returning. A nanosecond is one-billionth of a second (10E-9), and most common implementations of the Java VM don't truly support this fine a resolution of time. For this reason, the use of the method is currently quite rare. 
  The same, wait (long), but a more precise time settings can be set up a few nanoseconds, but it is generally not the realization of this virtual machine method. 
  When to Use notifyAll () Instead of notify () 
  The fundamental difference between notify () and notifyAll () is that if more than one thread is simultaneously waiting for notification, notify () will provide notification to only one of the waiting threads, whereas notifyAll () will provide notification to all of them. If your code is well defended against early notifications (discussed later), and notifyAll () is generally the better choice. 
  The major disadvantage of notifyAll () is that it is wasteful of processor resources if all but one of the notified threads will end up waiting again. This is a situation that is difficult to guarantee. If your code synchronizes on this either through synchronized blocks or the synchronized method modifier, you can't be sure that some code external to the class won't synchronize and wait on a reference to the object. If that happens, notify () might signal the thread running that external code instead of the thread that you intended. Consider a situation where you have a class, ClassX, with two methods: 
  Lock with a locking different ways to this type of internal locking, the external category can be locked to these examples, a number of threads waiting for the lock, notify () will not necessarily notice to the expectations of threads. 
  ClassX category in the following two synchronized methods, which included a wait / notify 
  Public synchronized void waitUntilTrue () 
  Throws InterruptedException ( 
  While (value == false) ( 
  Wait (); 
  ) 
  ) 
  Public synchronized void setValue (boolean newValue) ( 
  If (newValue! = Value) ( 
  Value = newValue; 
  Notify (); / / notifyAll () might be safer … 
  ) 
  ) 
  At the same time, external ClassY category, generating ClassX examples, examples of this on the wait () 
  In addition, there's an external class, ClassY, with this code in one of its methods: 
  ClassX cx = new ClassX (); 
  Cx.setValue (false); 
  / / … 
  Synchronized (cx) ( 
  Cx.wait (); / / trouble 
  ) 
  If threadA is running inside ClassY, it synchronizes on cx and invokes wait (). If threadB invokes waitUntilTrue (), it is now also waiting for notification. If threadC invokes setValue () and passes true (a new value), threadC will only notify one thread because notifyAll () wasn't used. There's no way to be sure whether threadA or threadB will be notified. In this situation, notifyAll () would have guaranteed that they would both be notified. 
  At this point if there are three threads: threadA in ClassY operation, and wait for synchronous cx; threadB call the waitUntilTrue cx () wait; threadC call cx the setValue (), it can only threadA notice, in a B, no way to determine which one to be notified.    NotifyAll () ensure that both be notified. 
  It is generally safe to use notify () only when you can guarantee that only one thread will ever be waiting for notification. This is a relatively unusual occurrence. 
  There is only one thread, the use notify () 
  If you're not sure whether you need to use notify () or notifyAll (), use notifyAll (). It might be a little wasteful, but it's safer. 
  If you are unsure which one to use, the use of notifyAll (), right? 

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • DotNetKicks
  • DZone
  • Netvouz
  • Propeller

Tags: , ,

Releated Java Articles

Comments

Leave a Reply