Basic threading Operations in Java
This is the thread state switch legend given earlier, and may not fully understand the switching conditions in it, and we will detail how these thread states are manipulated in Java.
This article will explain notify, Notifyall, interrupt, join, and sleep operations.
NotifyAnd
NotifyallOperation
NotifyThe work of the method
Explained by code:
PackageCom.zczpeng.thread; Public class notifytheadtest { /** * @param args * * Public Static void Main(string[] args) {NewThread (NewParentthread ()). Start (); }}class Parentthread implements runnable{/** * This object, which is held for each Childthread object, simulates the exclusive behavior of all thread objects */ Public Static FinalObject Thread_lock =NewObject ();@Override Public void Run() {/** * Start three threads that independently preempt a Thread_lock object */ for(inti =0;i<3; i++) {Childthread Cthread =NewChildthread ();NewThread (Cthread). Start (); }/** * In synchronized this line add a breakpoint, to ensure that this part of the final execution. */ synchronized(Thread_lock) {thread_lock.notify (); }}}class Childthread implements runnable{@Override Public void Run() {Thread t = thread.currentthread ();Longid = T.getid (); System.out.println ("Threads"+id+"Start successfully, wait for execution ...");synchronized(Parentthread.thread_lock) {Try{ParentThread.THREAD_LOCK.wait (); }Catch(Interruptedexception e) {E.printstacktrace (); } }//Description thread has been awakenedSystem.out.println ("Threads"+id+"carried out."); }}
In the above two pieces of code, the Parentthread class is responsible for creating objects of three childthread classes, each of which holds parentthread for each instance object of the Childthread class. Thread_lock the "key" of the object and exits Parentthread through the wait method. Thread_lock the exclusive state of the object (but does not return the lock)
Then we pass the Parentthread in the Parentthread class. Thread_lock. Notify () method unblock state:
synchronized (THREAD_LOCK) { THREAD_LOCK.notify();}
The above code performs as follows:
In fact, we only know that there are three instance objects in the Childthread class that are waiting for parentthread. The "lock core" of the Thread_lock object is idle; we don't know parentthread. The Thread_lock.notify () method will parentthread. The "Lock core" (exclusive right) of the Thread_lock object is given to which thread of the three threads (the decision process is done by the operating system). And we also know that parentthread. The Thread_lock.notify () method will only wake up waiting for Parentthread. One of the instance objects of the three childthread classes of the Thread_lock object "lock Core" (exclusive rights).
NotifyallThe work of the method
Actually understanding the work of the Notify () method, it is not difficult to understand the work of the Notifyall () method. Next, the same code as in the above section, we will parentthread the Parentthread in the class. Thread_lock.notify () method, replaced with Parentthread. Thread_lock.notifyall () method. As shown in the following code snippet:
synchronized (THREAD_LOCK) { THREAD_LOCK.notifyAll(); }
Then we observe the result of the code execution:
Wait for Parentthread. The three threads of the lock core (exclusive) of the Thread_lock object lock are sequentially woken up (exclusive rights in turn).
Interrupt Signal
Interrupt, the meaning of the word itself is interrupted, terminated, blocked. When a thread receives this signal (command), it will set its own state attribute to "interrupted", but the thread itself will not terminate immediately. The programmer needs to decide how to proceed with the thread's next activity based on this state attribute.
is a thread state change diagram in the article, and we already know that the thread can be in many different states since it was created: Ready (running), running, blocking (waiting), dying. It is not the thread that is in any state that can receive the interrupt signal. If the thread is in a blocking state (wait (), wait (time), or sleep-induced) when the interrupt signal is received, the thread throws a Interruptedexception exception:
When thread receives a interrupt signal, there are two possible results: either the Isinterrupt property in its thread object is set to True, or the interruptedexception exception is thrown. Note that if the interruptedexception exception is thrown, its Isinterrupt property is not set to true.
code Example
Here we pass a test code to illustrate the operation of the interrupt signal:
Public classInterruptprocessor { Public Static void Main(string[] args) throws Exception {// Thread one threadsThread Threadone =NewThread (NewRunnable () {@Override Public void Run() {Thread CurrentThread = Thread.CurrentThread (); while(!currentthread.isinterrupted ()) {/ * * Print a word here saying the loop is running * */System. out. println ("Thread one is always running!" "); } System. out. println ("thread one ends normally!" "+ currentthread.isinterrupted ()); } });// thread of threadThread Threadtwo =NewThread (NewRunnable () {@Override Public void Run() {Thread CurrentThread = Thread.CurrentThread (); while(!currentthread.isinterrupted ()) {synchronized (CurrentThread) {Try{//Through wait to enter the blockCurrentthread.wait (); }Catch(Interruptedexception e) {E.printstacktrace (System. out); System. out. println ("Thread of the interrupt signal, the abnormal end!" "+ currentthread.isinterrupted ());return; }}} System. out. println ("thread" ends normally! "); } }); Threadone.start (); Threadtwo.start ();//You can hit the upper point here to ensure that the Threadone and Threadtwo have completed the bootSystem. out. println ("Two threads are working properly and starting to signal a break"); Threadone.interrupt (); Threadtwo.interrupt (); }}
In the example code above, we created two threads Threadone and Threadtwo. Where Threadone threads have been circulating without any blocking (although this is not recommended in a formal environment, but here we are trying to simulate the running state of this thread), each loop detects the value of the thread's Isinterrupt property at a time, If a value of true is found to terminate the loop, the other threadtwo thread enters the blocking state immediately after startup, waiting to wake up (no other thread actually wakes it to simulate the state of the thread blocking).
At this point we send a interrupt signal to two threads. The following are the results of the execution of two threads:
Thread one is always running!
Thread one is always running!
Thread one ends normally! True
Java.lang.InterruptedException
At java.lang.Object.wait (Native Method)
At Java.lang.Object.wait (object.java:503)
At Test.thread.interrupt.interruptprocessor$2.run (interruptprocessor.java:34)
At Java.lang.Thread.run (Unknown Source)
Thread of the interrupt signal, the end of the abnormal! False
By displaying the result, we see that the Isinterrupt property of the Threadone thread is successfully set to True, the loop normal end thread is running normally, and the threadtwo thread is in a blocking state caused by wait (), so after receiving the interrupt signal, Throws an exception whose Isinterrupt property is still false;
JOIN Operation
The join operation makes the execution of the two threads sequential, specifically: if a thread invokes the join operation of the b thread, a thread waits (or waits for a specified length of time) until the B thread executes (dead state) a thread continues to execute. As shown in the following:
Here we show a sample code in which we create two threads: one is the thread that the Main method executes (recorded as Mainthread) and the other is a thread called Jointhread. Next we call Jointhread's Join method in Mainthread, so that the mainthread thread blocks until the jointhread thread executes, and then continues execution.
PackageCom.zczpeng.thread; Public class jointhread implements Runnable { Public Static void Main(string[] args) {Thread thread = Thread.CurrentThread ();Longid = Thread.getid (); System.out.println ("Main thread"+ ID +"Running"); Thread Jointhread =NewThread (NewJointhread ()); Jointhread.start ();Try{//If this line is not available, the result of the run may be result 1, with this line, the result must be the result 2Jointhread.join (); System.out.println ("Main thread"+ ID +"Run the bundle"); }Catch(Interruptedexception e) {E.printstacktrace (); } }@Override Public void Run() {Thread CurrentThread = Thread.CurrentThread ();Longid = Currentthread.getid (); System.out.println ("Threads"+ ID +"Start successfully, ready to enter the waiting state (5 seconds)");//Using the Sleep method, the model this thread executes the business code process Try{Thread.Sleep ( the); }Catch(Interruptedexception e) {System.out.println (E.getmessage ()); }//Execute here to indicate that the thread has been awakenedSystem.out.println ("Threads"+ ID +"Execution is complete!" "); }}
The following are the results of the execution:
If the join is not added, run result 1:
But with the result of the join running 2:
Note: The thread that calls the join method will also throw a interruptedexception exception if it receives a interrupt signal.
Join (), join (Millis), and join (Millis, Nanos)
In Java's basic threading operations, join (), join (Millis), and join (Millis, Nanos) can be used to wait on the target thread, and the differences between the three methods are mainly in the wait time:
Join: the equivalent of calling join (0), that is, waiting until the target thread runs to the end, the current calling thread can continue execution;
Join (Millis, Nanos): The calling thread waits Millis milliseconds + Nanos nanoseconds, regardless of whether the target thread executes or not, the current calling thread will continue to execute In fact, the description of the Join method is not accurate: The second parameter Nanos is only a reference value (the correction value), and only if it is greater than or equal to 500000, the second parameter will function (Nanosecond is One-zero of a second). Take a look at the source code for this method:
Public Final synchronized void Join(LongMillis,intNanosthrowsinterruptedexception {if(Millis <0) {Throw NewIllegalArgumentException ("Timeout value is negative"); }if(Nanos <0|| Nanos >999999) {Throw NewIllegalArgumentException ("nanosecond timeout value out of range"); }if(Nanos >=500000|| (Nanos! =0&& Millis = =0)) {millis++; } join (Millis);}
The above is the source code for the join (Millis, Nanos) method in JDK1.7. As we can see from the source code, this parameter only makes sense if the Nanos is greater than or equal to 500000 nanoseconds. And its role is not to allow the calling thread to wait for the exact number of nanoseconds specified by the parameter.
Sleep Operation
Sleep enters the blocking state of the current thread and does not release the exclusive state of any object locks that the thread occupies. Please note here:
The current thread, which is the thread that is currently calling the sleep method. Instead of the target thread being called. Take a look at the following code snippet:
Thread=Thread.currentThread();Thread=newThread(new SleepThread());joinThread.start();joinThread.sleep(50000);
Excuse me, which one is the blocked thread? CurrentThread or Jointhread? Think for 1 seconds,,, those in the heart answer "Jointhread" classmate, explained still did not understand the meaning of sleep method: Please pay attention to "current thread", into the blocking state must be "CurrentThread". This is why the sleep method is a static method.
The sleep method is not the same as the execution of the wait method: The Sleep method does not release the object lock exclusive mode occupied by the current thread. Please look at the following code snippet:
Public class join2thread implements Runnable { Public Static void Main(string[] args)throwsException {Thread JoinThread1 =NewThread (NewJoin2thread ()); Jointhread1.start (); Thread joinThread2 =NewThread (NewJoin2thread ()); Jointhread2.start (); }@Override Public void Run() {//Using the Sleep method, the model this thread executes the business code process Try{synchronized(Join2thread.class) {thread.sleep (long.max_value); } }Catch(Interruptedexception e) {Logger.error (E.getmessage (), E); } }}
How many threads can get Join2thread.class Object lock key (exclusive Join2thread.class object lock preemption)?
When the object lock is checked by JoinThread1, the Join2thread.class object is found to have no other thread exclusive, so it obtains the exclusive rights of the Join2thread.class object lock and executes to "Long.max_value" Because sleep does not release any object lock exclusive rights for this JOINTHREAD1 thread (the exclusive rights of the Join2thread.class object lock will certainly not be released);
Then when the joinThread2 thread makes a Join2thread.class object lock exclusive Check is, it is found that it is still occupied by the JOINTHREAD1 thread. So the joinThread2 thread waits in the bounding area and cannot get the key to the Join2thread.class object lock.
So there is only one thread that can have the Join2thread.class object lock key: JoinThread1.
Summary
This article describes the basic operations of thread threads in Java. Includes: Notify, Notifyall, wait, join, sleep, interrupt, etc. With these actions, the reader has been able to manipulate the threads to switch jobs in a variety of different states. Of course, these methods are not all Java threads, such as Destroy, stop, resume, and so on, but these operations have been eliminated (because they are unsafe).
Java Multithreaded Research 03-Basic operation of Threads (Notify,notifyall,interrupt,join,sleep)