Tag: sys lin Blank alt while loop DNA ack BSP catch
This article focuses on the use of the wait () method in Java multi-threading with the Notify ()/notifyall () Method.
The ①wait () and Notify/notifyall methods must be used in a synchronous code block
②wait () and Notify/notifyall () execution process
③ Interrupt calls the wait () method to enter the thread waiting for the queue
④notify The order of notifications can not be wrong
⑤ test a condition change with if or while in multiple threads?
The ①wait () and Notify/notifyall methods must be used in a synchronous code block
Wait () and Notify/notifyall () are methods of the object class, and when you execute two methods, you get the lock First. So how do we get the lock?
In this article: Java multi-thread synchronized Keyword--object lock features the article describes the use of the Synchronized keyword to obtain a lock. therefore, wait () and Notify/notifyall () are often used in conjunction with synchronized, that is, the wait () and Notify/notifyall () methods are called in the Synchronized-modified synchronous code block or Method.
②wait () and Notify/notifyall () execution process
Since wait () and Notify/notifyall () are placed in the synchronous code block, the thread must have entered the critical section when executing them, that is, the thread must have been locked.
When the thread executes wait (), it releases the current lock and then yields the CPU and enters the wait State.
When the Notify/notifyall method is executed, a thread that waits for the lock on the object is awakened, and then continues to execute until the lock is released after execution of the lock-locked area of the Exit object (the synchronized-decorated code block).
As can be seen here, Notify/notifyall () does not release the lock immediately after execution, but waits until the code in the critical section is executed and then Released. therefore, in actual programming, we should try to exit the critical section immediately after calling Notify/notifyall () on the Thread. That is, do not write some time-consuming code behind Notify/notifyall ().
Examples are as Follows: (excerpt from the Java multithreading core Technology)
1 public class Service {2 3 public void TestMethod (Object Lock) {4 try {5 synchronized (lock) {6 System.out.println ("begin Wait () threadname=" 7 + thread.currentthread (). GETN Ame ()); 8 lock.wait (); 9 System.out.println ("end Wait () threadname=" + thread.currentthread (). getName ());}12} catch (interruptedexception e) {e.printstacktrace (); 14}15}16 + public void Synnotifymethod (Object lock) {try {synchronized (lock) {S) Ystem.out.println ("begin Notify () threadname=" + thread.currentthread (). getName () + "time=" 22 + system.currenttimemillis ()); lock.notify (); thread.sleep (5000 ); System.out.println ("end Notify () threadname=" + thread.curRentthread (). getName () + "time=" + system.currenttimemillis ());}29} Cat Ch (interruptedexception e) {e.printstacktrace (); 31}32}33}
Call wait () in line 3rd of TestMethod () and call notify () in Synnotifymethod () on line 17th
As you can see from the code above, wait () and Notify/notifyall () are placed in the synchronous code block to be able to execute. If you do not obtain an appropriate object lock before executing wait () and Notify/notifyall (), you will throw: java.lang.IllegalMonitorStateException Exception.
In line 8th, when the Threada thread executes lock.wait (), This statement releases the acquired object lock lock and discards the CPU to enter the waiting Queue.
When another thread executes line 23rd Lock.notify (), it wakes threada, but at this point it does not immediately release the lock , then it sleeps for 5 seconds (sleep () does not release the lock, in fact sleep () can not be called in the synchronous code block, The lock is not released until the 28th line exits the critical section of the synchronized Modifier. At this point, the Threada has the opportunity to obtain a lock released by another thread and start execution from where it is waiting (line 24th).
Next is the two thread class, the thread class Threada calls the TestMethod () method to execute lock.wait (), when it is suspended, another thread class Synnotifymethodthread call Synnotifymethod () is responsible for waking up the suspended Thread. The code is as Follows:
1 public class Threada extends Thread {2 private Object lock, 3 4 public Threada (Object lock) {5 Super () ; 6 This.lock = lock; 7 } 8 9 @Override10 public void run () {one Service service = new service (); 12< C10/>service.testmethod (lock); }14}15 public class Synnotifymethodthread extends Thread {+ private Object lock;18 public synnotifymethodthread (object lock) { Super (); this.lock = lock;22 } @Override25 public void run () { Service service = new service (); Service.synnotifymethod (lock); }29}
And then the test class:
1 public class Test {2 3 public static void main (string[] Args) throws Interruptedexception {4 5 Object Lock = new Object (); 6 7 Threada a = new Threada (lock), 8 a.start (), 9 notifythread notifythread = new Notifythread (lock); 1 1 notifythread.start (); synnotifymethodthread c = new Synnotifymethodthread (lock); C.start (); 15 }16}
③ Interrupt calls the wait () method to enter the thread waiting for the queue
The sample code is as Follows:
1 public class Service {2 3 public void TestMethod (Object lock) {4 try {5 synchronized (lock) {6 S) Ystem.out.println ("begin Wait ()"); 7 lock.wait (); 8 System.out.println (" end wait ()"); 9 }10 } catch (interruptedexception e) {11 e.printstacktrace (); System.out.println ("exception"); }14 }15}16, public class Threada extends Thread {in private Object Loc k;20 public Threada (Object lock) { Super (); this.lock = lock;24 }25 @Override27 Public void Run () { Service service = new service (); Service.testmethod (lock); }31}
Note that the wait () method on line 23rd is called by the object lock of the objects class. The following interrupt () method is called by an object of the Threada class. In threada, the object is passed as an argument to the TestMethod () method, Threada's Run () method calls TestMethod (), and wait () pauses the Threada thread (pauses the currently executing wait () Threads). One difference can be seen from here:
Thread-related methods in the object Class:
1) Notify/notifyall
2) wait ()/wait (long)
Methods associated with the Java.lang.Thread:
1) Interrupt ()
2) Sleep ()/sleep (long)
3) Join ()/suspend ()/resume () ....
The test class code is as Follows:
1 public class Test {2 3 public static void main (string[] Args) {4 5 try {6 Object lock = new OBJEC T (); 7 8 Threada a = new Threada (lock); 9 a.start (); thread.sleep (); a.interrupt (); 14 } catch (interruptedexception e) { e.printstacktrace (); }17 }18}
When interrupt () is executed on line 13th, the thread in wait is "immediately" awakened (usually in response to an interrupt request immediately) and throws an Exception. At this point, the thread is Finished.
④notify The order of notifications can not be wrong
Assuming that wait () is executed in thread a, execute notify () in thread B. however, If thread B executes notify () and then ends, thread A does not go to wait (), then thread A will not be able to wake up normally (you can also wake ^~^ by throwing an exception by interrupt () method mentioned in ③).
This article: the ③ point in the method of communication between threads of Java multithreading mentions that an error in the sequence of notify notifications causes the thread that calls wait () to enter the waiting queue to no longer be awakened.
⑤ test a condition change with if or while in multiple threads?
I've never known it before. when a condition needs to be tested in the run () method of a thread, why use while instead of if??? Until I saw this simple example, I finally understood ....
The example is This:
There are two threads that delete data from the list, and only one thread adds data to the List. initially, the list is empty and the data in the list can be deleted only after the data has been added to the List. When the thread that added the data added data to the list, called Notifyall (), woke up two delete threads, but it only added one data and now has two wake-up delete threads, what do i do??
If you test the number of data in the list with the if, you will get a indexoutofboundexception, out-of-bounds exception. The reason is that the list has only one data, the first delete thread after the data is deleted, the second thread to perform the delete operation, the deletion fails, thereby throwing Indexoutofboundexception.
however, If you use while to test the number of data in the list, there will be no cross-border exceptions !!! Magic.
when the wait condition changes, the logic of the program is confusing ---that there is no data in the list, and then the thread goes to perform the operation of deleting the Data. therefore, it is necessary to use the while loop to determine the condition change, rather than using the If.
Examples are as follows: from the core technology of Java multithreaded programming
The Add class is responsible for adding data:
public class Add { private String lock; Public Add (String lock) { Super (); This.lock = lock; } public void Add () { synchronized (lock) { ValueObject.list.add ("anystring"); Lock.notifyall ();}}}
public class Threadadd extends Thread {
Private Add p;
Public Threadadd (Add P) {
Super ();
THIS.P = p;
}
@Override
public void Run () {
P.add ();
}
}
The subtract class, which is responsible for deleting the data---- first to make a conditional judgment and then execute wait (), which means: wait waits for the condition may change!!!
public class Subtract {private String lock; Public Subtract (String Lock) {super (); This.lock = lock; } public void Subtract () {try {synchronized (lock) {if (ValueObject.list.size () = = 0 {//change the IF to a while to ensure there is no out-of-bounds exception!!!! System.out.println ("wait begin threadname=" + thread.currentthread (). getName ()); Lock.wait (); System.out.println ("wait End threadname=" + thread.currentthread (). getName ()); } ValueObject.list.remove (0); System.out.println ("list size=" + ValueObject.list.size ()); }} catch (interruptedexception e) {e.printstacktrace (); } }}
public class Threadsubtract extends Thread {
Private Subtract r;
Public Threadsubtract (Subtract R) {
Super ();
THIS.R = r;
}
@Override
public void Run () {
R.subtract ();
}
}
Encapsulated List Queue:
public class Valueobject {public static List list = new ArrayList ();}
Test Class:
public class Run {public static void main (string[] Args) throws Interruptedexception { string lock = new String (" "); Add add = new Add (lock); Subtract Subtract = new Subtract (lock); Threadsubtract subtract1thread = new Threadsubtract (subtract); Subtract1thread.setname ("subtract1thread"); Subtract1thread.start (); Threadsubtract subtract2thread = new Threadsubtract (subtract); Subtract2thread.setname ("subtract2thread"); Subtract2thread.start (); Thread.Sleep (+); Threadadd addthread = new Threadadd (add); Addthread.setname ("addthread"); Addthread.start (); }}
Java multi-thread wait/notify