preface

Thread concurrency series:

Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Java Thread State Unsafe/CAS/LockSupport Application and principle Java concurrency “lock” nature (step by step to implement the lock) Java Synchronized implementation of mutual exclusion application and source exploration Java object header analysis and use (Synchronized related) Java The evolution process of Synchronized partial lock/lightweight lock/heavyweight lock Java Synchronized principle of heavyweight lock in depth (mutual exclusion) Java Synchronized principle of heavyweight lock in depth (synchronization) Java concurrency AQS In-depth analysis (on) the Java concurrency of AQS deep parsing (under) Java Thread. Sleep/Thread. Join/Thread. The yield/Object. Wait/Condition. Await explanation of Java concurrency Already the thorough analysis of concurrent Java (with Synchronized difference) Java Semaphore/CountDownLatch/CyclicBarrier ReentrantReadWriteLock in-depth analysis Deep parsing (principle), Java Semaphore CountDownLatch/CyclicBarrier in-depth analytical (application), the most detailed graphic analytic Java various locks (ultimate) thread pool will understand series

In Android development, it is inevitable to use threads to execute time-consuming tasks, so what if we want to stop/interrupt the execution of tasks in mid-stream? Let’s start with a simple thread.

private Thread threadOne = new Thread(new Runnable() { @Override public void run() { try { while(true) { Log.d(TAG, "thread isAlive:" + threadOne.isAlive()); Thread.sleep(1000); } } catch (Exception e) { Log.d(TAG, e.getClass().toString()); Log.d(TAG, "thread isAlive in catch:" + threadOne.isAlive()); }}});Copy the code

Normal operation print result:

                Log.d(TAG, e.getClass().toString());
                Log.d(TAG, "thread isInterrupted::" + threadOne.isInterrupted());
                Log.d(TAG, "thread isAlive in catch:" + threadOne.isAlive());
Copy the code

However, the interrupt status bit is still “not interrupted”. This is not quite what we expected, so recall which method threw the exception and it was the sleep method.

// BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
    public static void sleep(long millis) throws InterruptedException {
        sleep(millis, 0);
    }

Copy the code

Let’s comment out the sleep() method and run it again

private Thread threadOne = new Thread(new Runnable() { @Override public void run() { try { while (! threadOne.isInterrupted()) { Log.d(TAG, "thread isAlive:" + threadOne.isAlive()); } Log.d(TAG, "break while thread isAlive:" + threadOne.isAlive()); Log.d(TAG, "break while thread isInterrupted::" + threadOne.isInterrupted()); } catch (Exception e) { Log.d(TAG, e.getClass().toString()); Log.d(TAG, "thread isInterrupted::" + threadOne.isInterrupted()); Log.d(TAG, "thread isAlive in catch:" + threadOne.isAlive()); }}});Copy the code

This time the result matches our “intuitive imagination”, the thread is still alive, but the interrupt status bit is marked as true.

1. InterruptedException is thrown if the thread is blocking (sleep). The interrupt flag bit is false. 2. Interrupt threads that are not blocked, and the interrupt flag bit is set to true.

For threads that are blocking, simply catch InterruptedException and exit the thread. For threads that are not blocking, determine whether the interrupt flag is true and exit the thread. Of course, if we call another method in the thread, we are not sure whether the other method blocks or not, so we can combine the two judgments as follows:

private Thread threadOne = new Thread(new Runnable() { @Override public void run() { try { while (! threadOne.isInterrupted()) { doSomething(); } } catch (Exception e) { if (e instanceof InterruptedException) { isInterrupted = true; }}}});Copy the code

You might be wondering if your thread is running in a while, but if it only runs once, how can it be interrupted? It can only be stopped at every critical point possible.

private Thread threadOne = new Thread(new Runnable() { @Override public void run() { try { if (! threadOne.isInterrupted()) doSomething1(); else return; if (! threadOne.isInterrupted()) doSomething2(); else return; if (! threadOne.isInterrupted()) doSomething3(); else return; } catch (Exception e) { } } });Copy the code

Are there any other methods besides sleep that throw an exception? In fact, Thread explains all of this in the source code. Let’s take a look at the source code.

/** * Interrupts this thread. * * <p> Unless the current thread is interrupting itself, which is * always permitted, the {@link #checkAccess() checkAccess} method * of this thread is invoked, which may cause a {@link * SecurityException} to be thrown. * * <p> If this thread is blocked in an invocation of the {@link * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link * Object#wait(long, int) wait(long, int)} methods of the {@link Object} * class, or of the {@link #join()}, {@link #join(long)}, {@link * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, * methods of this class, then its interrupt status will be cleared and it * will receive an {@link InterruptedException}. * * <p> If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel InterruptibleChannel} * then the channel will be closed, the thread's interrupt * status will be set, and the thread will receive a {@link * java.nio.channels.ClosedByInterruptException}. * * <p> If this thread is blocked in a {@link java.nio.channels.Selector} * then the thread's interrupt status will be set and it will return * immediately from the selection operation, possibly with a non-zero * value, just as if the selector's {@link * java.nio.channels.Selector#wakeup wakeup} method were invoked. * * <p> If none of the  previous conditions hold then this thread's interrupt * status will be set. </p>Copy the code

To sum up:

  • When a thread is interrupted, the interrupt status bit is reset to false. InterruptedException is thrown (this is why Thread.isinterrupted () is false in our first example)
  • In the thread using nio InterruptibleChannel interface, when the thread is interrupted, the interrupted status will be reset to true, and throw ClosedByInterruptException anomalies
  • When using a NIO Selector in a thread, the interrupt status bit is reset to true when the thread is interrupted
  • If not, the interrupt status bit is reset to true (for cases where there is no blocking as described above).

Difference between thread.isinterrupted () and thread.interrupted () Thread.isinterrupted () is an object method that indicates the interrupted status of a thread. Thread.interrupted() is a static method that indicates the interrupted status of the current Thread, for example:

        Log.d(TAG, " curThread is:" + Thread.currentThread().getName());
        Log.d(TAG, " Thread.currentThread().isInterrupted() before :" + Thread.currentThread().isInterrupted());
        Log.d(TAG, " Thread.interrupted() before :" + Thread.interrupted());
        Log.d(TAG, " threadOne.isInterrupted() before :" + threadOne.isInterrupted());
        Thread.currentThread().interrupt();
        Log.d(TAG, " Thread.currentThread().isInterrupted() after:" + Thread.currentThread().isInterrupted());
        Log.d(TAG, " Thread.interrupted() after :" + Thread.interrupted());
        Log.d(TAG, " Thread.currentThread().isInterrupted() after2:" + Thread.currentThread().isInterrupted());
        Log.d(TAG, " threadOne.isInterrupted() after :" + threadOne.isInterrupted());
Copy the code

As you can see from the above, thread.interrupted () resets the interrupt status to false, but thread.isinterrupted () does not.

conclusion

Thread.interrupt () InterruptedException is thrown when thread.interrupt() is running in a WAITING/TIMED_WAITING state. If the thread interrupt flag bit is false, the thread stops running. When thread.interrupt() is executed, no exception will be raised. The thread does not stop running because its interrupt bit is true. 3. If a thread is BLOCKED(Synchronized), thread.interrupt() will not raise an exception, the thread interrupt flag is true, and the thread does not stop running.

To learn more about thread state, go to Java Thread State

If you like, please like, pay attention to your encouragement is my motivation to move forward

Continue to update, with me step by step system, in-depth study of Android

More dry goods, public search [small fish love programming]