Respect for the original: http://blog.csdn.net/yuanzeyao/article/details/47186167
Thread.Interrupt really can break the thread?
In peacetime development process, believe will use to multi-threading, in the use of multi-threading, we will encounter a variety of problems, today we say a multi-threaded problem-thread interruption. It's very easy to start a thread in Java, and in most cases I'm going to let a thread run its own task and then stop on its own, but sometimes we need to cancel something, like when you download it on the web and sometimes you need to cancel it. It is not easy to implement a thread-safe interrupt because Java does not support the mechanism of a safe and fast threading thread, and it is estimated that many students will say that Java does not provide a Thread.interrupt way to break threads, OK, we start with this method today.
But does calling this method line threads stop? We'll find out by writing a demo.
Public class Main { Private Static FinalString TAG ="Main"; Public Static void Main(string[] args) {Thread t=NewThread (NewNrunnable ()); T.start (); System.out.println ("is start ...");Try{Thread.Sleep ( the); }Catch(Interruptedexception e) {} t.interrupt (); System.out.println ("is interrupt ..."); } Public Static class nrunnable implements Runnable { @Override Public void Run() { while(true) {System.out.println ("I have no kind of interruption.");Try{Thread.Sleep ( +); }Catch(Interruptedexception e) { } } } }}
If the INTERRUTP method is able to break the thread, then it prints the is interrupt .... Then there should be no log, let's take a look at the results.
is start.......我没有种中断我没有种中断我没有种中断我没有种中断我没有种中断is interrupt.......我没有种中断我没有种中断我没有种中断我没有种中断我没有种中断....
Results show that the child threads are not interrupted
So Thread.interrupt() the method does not interrupt the thread, this method simply tells the thread that there is an interrupt request outside, and whether the interrupt depends on the thread itself. In the thread class interrupt() there are two other very similar methods in addition to methods: interrupted and isInterrupted methods, which are described in the following ways:
interruptThis method is an instance method that tells the thread that there is an interrupt request outside and sets the break token in the thread to True
interruptedThis method is a class method that tests whether the front thread has been interrupted. The interrupt state of the thread is purged by this method. In other words, if the method is called twice in a row, the second call will return False (except in the case where the current thread is interrupted again until the first call has cleared its break state and the second call has finished verifying the break state).
isInterruptedThis method is an instance method that tests whether the thread has been interrupted. The interrupt state of the thread is not affected by the method. A thread break is ignored because a thread that is not active at the time of the break reflects the method that returns false
Common methods for handling thread interrupts set cancellation token
Or with the above example, just made some changes.
Public Static void Main(string[] args) {nrunnable run=NewNrunnable (); Thread t=NewThread (run); T.start (); System.out.println ("is start ...");Try{Thread.Sleep ( the); }Catch(Interruptedexception e) {} run.cancel (); System.out.println ("Cancel ..."+system.currenttimemillis ()); } Public Static class nrunnable implements Runnable { Public BooleanIscancel=false;@Override Public void Run() { while(!iscancel) {System.out.println ("I have no kind of interruption.");Try{Thread.Sleep (10000); }Catch(Interruptedexception e) {}} System.out.println ("I have finished ..."+system.currenttimemillis ()); } Public void Cancel() { This. iscancel=true; } }
The results of the implementation are as follows:
is start..........1438396915809我已经结束了...1438396922809
Through the results, we found that the thread has indeed been interrupted, but the attentive classmate should have found a problem, call the Cancel method and the last thread to complete the interval of several seconds, that is, the thread is not immediately interrupted, we analyze the reason below:
The condition that the child thread exits is when the loop ends, that is, the cancel flag is set to true, but when we call the Cancel method to set the Calcel tag to true, there is a time-consuming operation in the while loop (the Sleep method simulates), This flag is not checked until the time-consuming operation is completed, so the Cancel method and the thread exit are in the middle of the interval.
Pass
interruptAnd
isinterruptmethod to break the thread
Public Static void Main(string[] args) {Thread t=NewNthread (); T.start (); System.out.println ("is start ...");Try{Thread.Sleep ( the); }Catch(Interruptedexception e) {} System.out.println ("Start interrupt ..."+system.currenttimemillis ()); T.interrupt (); System.out.println ("End interrupt ..."+system.currenttimemillis ()); } Public Static class nthread extends Thread { @Override Public void Run() { while(! This. isinterrupted ()) {System.out.println ("I have no kind of interruption.");Try{Thread.Sleep (10000); }Catch(Interruptedexception e) {Thread.CurrentThread (). interrupt (); }} System.out.println ("I have finished ..."+system.currenttimemillis ()); } }}
The results of the operation are as follows:
is start.......我没有种中断start interrupt...1438398800110我已经结束了...1438398800110...1438398800110
This time is interrupted, but this method is limited, this method is only valid for the task that throws the exception, such as Java, and so on, InterruptedException sleep、wait for the task that does not throw such an exception, the effect is the same as the first method, there will be delay, One of the most important parts of this example is the cache statement, which we call to Thread.currentThread().interrupt() remove the code and run you will find that the thread cannot be terminated because the InterruptedException thread's interrupt flag is cleared when it is thrown, so if the current thread is interrupted in the while statement , the return is false. For the InterruptedException exception, I want to say is: must not catch the statement block do nothing, if you really do not want to deal with, you can throw the exception, let the call throw exception method also become a can InterruptedException throw
method, if you want to catch this exception, it is a good idea to call the method in the cache statement so that Thread.currentThread().interrupt(); the upper level simply interrupts the request and processes the interrupt.
There are limitations to both methods, and the first approach can only deal with tasks that do not have a lot of work and frequently check for cyclic flags, and for the second method it is appropriate for the code to be thrown InterruptedException . That is, the first and second methods support a thread task that supports interrupts, so what do you do with a thread task that does not support interrupts?
For example, if a thread is blocking because of synchronous I/O operations, the interrupt request will not be thrown InterruptedException , how can we break this thread?
Common way to handle thread interrupts that do not support interrupts interrupt methods for overwriting threads
Public Static class readerthread extends Thread { Public Static Final intBuffer_size= +; Socket socket; InputStream is; Public Readerthread(Socket socket)throwsIOException { This. Socket=socket; is= This. Socket.getinputstream (); }@Override Public void Interrupt() {Try{Socket.close (); }Catch(IOException e) { }finally{Super. interrupt (); }Super. interrupt (); }@Override Public void Run() {Try{byte[]buf=New byte[Buffer_size]; while(true) {intCount=is.read (BUF);if(count<0) Break;Else if(count>0) { } } }Catch(IOException e) { } } }}
For example, in the above example, the method of the thread is rewritten, when the method is called, the interrupt interrupt socket is closed, if the Read method is blocked at this time, then IOException the thread task will be thrown at the end.
The above method is implemented by rewriting threads interrupt , so how do you break the task of using the thread pool?
Newtaskfor method for overwriting thread pool
Usually we add a task to the thread pool in the following form:
Future<?> future=executor.submit(new Runnable(){ @Override publicvoidrun() { } });
When canceling a task, it calls the future Cancel method, in fact the thread's interrupt method is called in the Cancel method. So for tasks that do not support interrupts, Cancel is also invalid, so let's take a look at the Submit method.
publicsubmit(Runnable task) { ifnullthrownew NullPointerException(); null); execute(ftask); return ftask; }
Here is called the AbstractExecutorService newtaskfor method, then we can not rewrite Threadpoolexecutor newtaskfor method, next look I'm dealing with it
Defines a base class in which all tasks that need to be canceled inherit the base class
publicinterface CancelableRunnable<T> extends Runnable { publicvoid cancel(); public RunnableFuture<T> newTask();}
Change the readerthread above to inherit this class
Public Static class readerthread implements cancelablerunnable<Void> { Public Static Final intBuffer_size= +; Socket socket; InputStream is; PublicReaderthread (socket socket) throws IOException { This. Socket=socket; is= This. Socket.getinputstream (); } @Override Public voidRun () {Try{byte[]buf=New byte[Buffer_size]; while(true) {int Count=is.read (BUF);if(Count<0) Break;Else if(Count>0) { } } }Catch(IOException e) {}} @Override Public voidCancel () {Try{Socket.close (); }Catch(IOException e) {}} @Override PublicRunnablefuture<void> NewTask () {return NewFuturetask<void> ( This,NULL) {@Override Public BooleanCancelBooleanmayinterruptifrunning) {return Super. Cancel (mayinterruptifrunning);if(Readerthread. ThisInstanceof cancelablerunnable) {((cancelablerunnable) (Readerthread. This). Cancel (); }Else{Super. Cancel (mayinterruptifrunning); } } }; } }
When you invoke the future Cancel method, it closes the socket, eventually causing the Read method to be abnormal, thus terminating the thread task.
OK, about the thread interrupt mechanism to write here, interested students welcome message discussion ...
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Deep analysis of the Java threading Interrupt mechanism