The thread class also provides 2 class methods to stop a thread, except that it automatically enters a dead state, and can be stopped manually.
First, stop
, the Stop method has been marked as obsolete and is not recommended. Because this method is too violent, it will kill the process immediately, resulting in data not synchronizing, resulting in difficult to troubleshoot errors.
Here is the code that causes the error message:
1 Public classStopthreadunsafe {2 Public StaticUser U =NewUser ();3 4 Public Static classUser {5 Private intID;6 PrivateString name;7 8 9 PublicUser () {Ten This. id = 0; One This. Name = "0"; A } - - Public intgetId () { the returnID; - } - - Public voidSetId (intID) { + This. ID =ID; - } + A PublicString GetName () { at returnname; - } - - Public voidsetName (String name) { - This. Name =name; - } in - @Override to PublicString toString () { + return"User{" + -"id=" + ID + the", Name= ' + name + ' + ' + *‘}‘; $ }Panax Notoginseng } - the Public Static classChangeobjectthreadextendsThread { + volatile BooleanSTOPME =false; A the Public voidStopme () { +STOPME =true; - } $ $ @Override - Public voidrun () { - while(true) { the //if (STOPME) { - //System.out.println ("Exit by Stop Me");Wuyi //Break ; the // } - synchronized(u) { Wu intv = (int) (System.currenttimemillis ()/1000); - U.setid (v); About //pause for some time $ - Try { -Thread.Sleep (100); -}Catch(interruptedexception e) { A e.printstacktrace (); + } the //pause and then write value - U.setname (string.valueof (v)); $ } the Thread.yield (); the } the } the } - in Public Static classReadobjectthreadextendsThread { the @Override the Public voidrun () { About while(true) { the synchronized(u) { the if(U.getid ()! =Integer.parseint (U.getname ())) { the System.out.println (u.tostring ()); + } - } the Thread.yield ();Bayi } the } the } - - the Public Static voidMain (string[] args)throwsinterruptedexception { the NewReadobjectthread (). Start (); the while(true) { theThread T =NewChangeobjectthread (); - T.start (); theThread.Sleep (150); the t.stop (); the }94 } the}
Error code
The result of the operation is:
The inside condition is that the ID and name are the same value, but the thread is forced to stop, causing data confusion.
So how do you stop a thread?
Add a flag to the thread body, each time the line Cheng to see the benchmark, if the benchmark is valid, then automatically exit, such as the code, there is a Stopme method, at the appropriate time call can stop the thread, and is moderated, basically does not bring the problem of data loss.
Second, interrupt
Since stop is such a pit, all JDK still gives the solution, that is thread interrupt interrupt.
There are 4 methods for interrupt in the JDK,
Interrupt thread, the method is an instance method that notifies the target thread of a break, that is, to set the interrupt flag bit. , the interrupt flag bit identifies that the current thread has been interrupted.
Tips: Adding interrupts to threads does not make a real difference to a thread, it simply sets the interrupt flag bit and requires a series of exit operations to terminate the thread.
public boolean isinterrupted ()
Determines whether the current thread has been interrupted by checking the interrupt flag bit.
public static Boolean Interrupted ()
The interrupted is also used to determine the interrupt state of the current thread, but it also clears the interrupt flag bit state of the current thread.
Private Native Boolean isinterrupted (Boolean clearinterrupted)
code example:
1 /**2 * About interrupt interrupt3 * Created by Huxingyue on 2017/9/3.4 */5 Public classInterruptabout {6 Public Static voidMain (string[] args)throwsinterruptedexception {7Thread T1 =NewThread () {8 @Override9 Public voidrun () {Ten while(true) { One //This is a reasonable exit. A if(Thread.CurrentThread (). isinterrupted ()) { -System.out.println ("Here is interrupted"); - Break; the } -SYSTEM.OUT.PRINTLN ("a yield was performed here"); - -System.out.println ("1 is the current thread a break state?") "+Thread.CurrentThread (). isinterrupted ()); + Try { -SYSTEM.OUT.PRINTLN ("Prepare to sleep here"); +Thread.Sleep (2000); A}Catch(interruptedexception e) { atSystem.out.println ("Interrupted when sleep"); - //should be interrupted here again, Sleep reported an exception will clear the interrupt flag -System.out.println ("2 is the current thread a break state?") "+Thread.CurrentThread (). isinterrupted ()); - Thread.CurrentThread (). interrupt (); - } - in - Thread.yield (); to } + } - }; the T1.start (); *Thread.Sleep (2000); $ t1.interrupt ();Panax Notoginseng } -}
View Code
While there is an if to determine the thread's interrupt flag, if there is an interrupt flag, you can reasonably exit.
Note that when you call sleep (), you may be interrupted by the interrupt () method, which throws interruptedexception, not just throws an exception, but also clears the flag bit, so the interrupt flag is added again in the catch statement.
Terminating stop of thread and interrupt of thread interrupted