Ali Ant Financial from the interview questions

How do I stop/interrupt a running thread

The basic concept

What is an interrupt (Interrupt negotiation mechanism)?

  1. First, a thread should not be forced to suspend or stop by other threads, but should be stopped by the thread itself (so stop()/suspend()/resume() are deprecated).
  2. Second, there is no way to stop a thread immediately in Java, but it is important to stop a thread, such as canceling a time-consuming operation, so Java provides a mechanism for stopping a thread — interrupt
  3. Interrupt is a collaborative mechanism. Java does not add any syntax to interrupt, and it is entirely up to the programmer to implement this process. (To interrupt a thread, you need to manually adjust the interrupt method of the thread, which simply sets the interrupt flag of the thread object to true. Then you need to write your own code to constantly check the current thread’s identity bit. If true, it means that another thread has requested that the thread abort.)
  4. Each thread object has an identifier that identifies whether the thread has been interrupted; If the flag bit is true, it is interrupted; if the flag bit is false, it is not interrupted.

Set the thread’s identity bit to true by calling the interrupt method on the thread object; It can be called from another thread, or it can be called from its own thread

Interrupt the associated Api methods

methods explain
void interrupt() The instance method interrupt() simply sets the thread’s interrupt state to true and does not stop the thread
boolean interrupted() Static method, Thread.interrupted()

Determines whether the thread is interrupted and clears the current interrupted state

This method does two things

1. Return the interrupted status of the current thread

2. Set the interrupt status of the current thread to false
boolean isInterrupted() Determine if the current thread is interrupted (by checking the interrupt flag bit)

Interview Answers

  1. Thinking: constantly listen for interrupt status in the thread that needs to interrupt, and execute the appropriate interrupt handling business logic once an interrupt occurs
  2. The specific implementation
  • This is done with a volatile variable
    • Code implementation
static volatile Boolean isStop = false; Public static void main(String[] args) {new Thread(() -> {while (true) {if (isStop) {system.out.println (" < span style = "max-width: 100%; clear: both; break; } system.out. println(" I am a good little gyro, spin and spin --> isStop "+ isStop); } }, "t1").start(); // Try {timeunit.seconds.sleep (1); } catch (Exception e) { e.printStackTrace(); } new Thread(() -> {isStop = true; }, "t2").start(); }Copy the code
  • Implemented via AtomicBoolean
static AtomicBoolean atomicBoolean = new AtomicBoolean(false); public static void main(String[] args) { new Thread(() -> { while (true) { if (atomicBoolean.get()) { System.out.println(" atomicBoolean = > atomicBoolean "+ atomicBoolean); break; } system.out. println(" I am a good little top, spin and spin --> atomicBoolean value "+ atomicBoolean); } }, "t1").start(); // Try {timeunit.seconds.sleep (1); } catch (Exception e) { e.printStackTrace(); } new Thread(() -> {// set atomicBoolean to true atomicBoolea.set (true); }, "t2").start(); }Copy the code
  • Thread class interrupt API method to achieve
public static void main(String[] args) { Thread t1 = new Thread(() -> { while (true) { if (Thread.currentThread().isinterrupted ()) {// If the interrupt flag is true system.out.println (" little gyro, turn, turn, + thread.currentThread ().isinterrupted ()); break; } system.out.println (" thread.currentThread () + thread.currentThread ().isinterrupted ()); } }, "t1"); t1.start(); // Try {timeunit.seconds.sleep (1); } catch (Exception e) { e.printStackTrace(); } new Thread(() -> {// Set the interrupt flag bit to true t1.interrupt(); }, "t2").start(); }Copy the code

Interrupt () source code parsing

public void interrupt() { if (this ! = Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b ! = null) {// Just to set the interrupt flag calls the native method interrupt0() with an interrupt flag bit; b.interrupt(this); return; } } interrupt0(); } // Native method private native void Interrupt0 ();Copy the code

IsInterrupted (

public boolean isInterrupted() { return isInterrupted(false); } // Whether the native method ClearInterrupted clears the interrupt flag private native Boolean isInterrupted(Boolean ClearInterrupted);Copy the code

Interview question: Does the current thread stop immediately if its interrupt flag is true?

  1. When a thread calls interrupt:
    • If the thread is normally active, the thread’s interrupt flag bit is set to true, and that’s it. Threads with the interrupt flag bit set continue to run normally. So an interrupt does not really interrupt a thread, but only the thread itself
    • If you call the interrupt method on the current thread object in another thread while in the blocked state (sleep Wait Join, etc.), the thread immediately exits the blocked state and throws an InterruptedException
  2. Case 1: Interrupt true does not stop the program immediately
    • code
    public static void main(String[] args) { Thread t1 = new Thread(() -> { for (int i = 0; i <= 300; i++) { System.out.println("i --->" + i); } system.out.println (" + thread.currentThread ().isinterrupted ()); }, "t1"); t1.start(); System.out.println(" + thread.currentThread ().isinterrupted ()) + thread.currentThread ().isinterrupted ()); / / sleep two milliseconds try {TimeUnit. MICROSECONDS. Sleep (2); } catch (Exception e) { e.printStackTrace(); } // The instance method simply sets the thread's interrupt status position to true and does not stop the thread t1.interrupt(); System.out.println(" + thread.currentThread ().isinterrupted ()) + thread.currentThread ().isinterrupted ()); try { TimeUnit.MICROSECONDS.sleep(3000); } catch (Exception e) { e.printStackTrace(); System.out.println(" After calling interrupt(),t1's third interrupt identifier is the value: --->" + Thread.currentThread().isInterrupted()); }Copy the code
    • The output

  • Conclusion: Simply setting the interrupt flag to true after an interrupt call does not immediately stop the thread
  1. Case 3:
    • code
/** * The sleep method throws InterruptedException and sets the interrupt identifier to false. The catch method does not set the interrupt identifier to true by calling interrupt(). */ public static void main(String[] args) {Thread t1 = new Thread(() -> {while (true) {if (Thread.currentThread().isinterrupted ()) {// If true system.out.println (thread.currentThread ().getName() + "-- > + thread.currentThread ().isinterrupted () + "--> interrupted "); break; } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {thread.currentThread ().interrupt(); e.printStackTrace(); } system.out.println (thread.currentThread ().getName() + "-- > "+ thread.currentThread ().isinterrupted ()); } }, "t1"); t1.start(); try { TimeUnit.SECONDS.sleep(3); } catch (Exception e) { e.printStackTrace(); } t1.interrupt(); }Copy the code
  • The output

  • Conclusion: If the thread blocks while calling Object’s wait(), wait(long), or wait(long, int) methods or join(), Join (long), join(long, int) methods, Methods such as sleep(long) or sleep(long, int), in which the interrupted state is cleared and InterruptedException is received

  1. Conclusion: Interrupts are just a collaborative mechanism. Modifying the interrupt identifier is nothing more than that and will not stop the interrupt immediately

Interrupted () method

  1. code
Public static void main(String[] args) {system.out.println (" thread.interrupted () + thread.interrupted ()); System.out.println(" status before calling interrupt() 02: --> "+ thread.interrupted ()); System.out.println(" before calling interrupt() "); Thread.currentThread().interrupt(); System.out.println(" after calling interrupt() "); System.out.println(" status after calling interrupt() 03: --> "+ thread.interrupted ()); System.out.println(" status after calling interrupt() 04: --> "+ thread.interrupted ()); }Copy the code
  1. The output

  1. Conclusion: 1. Return the interrupted status of the current thread 2. Set the interrupted status of the current thread to false

  2. The source code parsing