The correct way to stop multithreading

Principle introduction:

Use interrupt to notify, not force

Best practice: how to stop threads correctly

  1. Normal stopping process (without external interference)
    1. The run() method has been executed
    2. There was an exception, but it was not caught
  2. Correct method: use interrupt to request to stop the thread
    1. Normal situation (there is no standard way to write sleep or wait methods in the run method)
    2. The thread may be blocked
    3. If the thread blocks after each work iteration (call the sleep method, etc.)
    4. If you don't write this, you will encounter a problem: the thread can't stop
      1. The problem of try/catch in while: the idea of java language when designing sleep function is to clear the interrupt flag bit in case of interrupt
public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            int num = 0;
            while (num <= 10000 && !Thread.currentThread().isInterrupted()) {
                try {
                    if (num % 100 == 0) {
                        System.out.println(num + "Is a multiple of 100");
                    }
                    num++;
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();
    }
  1. Coding habits to pay attention to in actual production development
    1. Two best treatment methods
      1. Priority: pass interrupt, direct throw exception
      2. Undesired or undeliverable: resume interrupt through Thread.currentThread().interrupt();
      3. Interrupts should not be masked
  2. Summary of a list of common methods that can throw interruptedexceptions in response to interrupts
    1. Object.wait()/wait(long)/wait(long,int)
    2. Thread.sleep(long)/sleep(long,int)
    3. Thread.join()/join(long)/join(long,int)
    4. java.util.concurrent.BlockingQueue.take()/put(E)
    5. java.util.concurrent.locks.Lock.lockInterruptibly()
    6. java.util.concurrent.CountDownLatch.await()
    7. java.util.concurrent.Exchanger.exchange(V)
    8. java.util.concurrent.CyclicBarrier.await()
    9. java.nio.channels.InterruptibleChannel related methods
    10. Related methods of java.nio.channels.Selector

Wrong stop method

  1. Deprecated stop, suspend, and resume methods
    1. Consequences of using stop
      • Using stop() to stop a thread will cause the thread to stop suddenly in the middle of its operation. It is impossible to complete the operation of a basic unit (a company), which will cause dirty data (some companies will receive more equipment and less equipment)
    2. Error theory about stop
      • Using stop cannot release the lock, which is wrong
    3. suspend questions
      • suspend suspends the thread, but does not release resources such as locks. Over time, it will cause deadlock
    4. Resume: resume the thread. It will not work if the thread has not been suspend ed before.
  2. Set Boolean flag bit with volatile
    • It seems feasible
    • Mistakes
      • It's blocked. I didn't check it
    • Correction method
      • It is solved by the interrupt method, not volatile
  3. Demonstrate volatile failure mode
/**
 * Demonstrate the limitations of volatile part2: volatile cannot stop a thread when it is blocked
 * In this example, the production speed of producers is fast and the consumption speed of consumers is slow
 * Therefore, when the blocking queue is full, producers will block and wait for consumers to consume further
 */
public class WrongWayVolatileCantStop {

    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<Object> storage = new ArrayBlockingQueue<>(10);
        Producer producer = new Producer(storage);
        Thread thread = new Thread(producer);
        thread.start();
        Thread.sleep(1000);
        Consumer consumer = new Consumer(storage);
        while (consumer.needMoreNums()) {
            System.out.println(consumer.storage.take() + "Consumed");
            Thread.sleep(100);
        }
        System.out.println("Consumers don't need more data...");
        // Once consumers don't need more data, producers should stop
        producer.canceled = true;

    }
}


class Producer implements Runnable {

    BlockingQueue storage;

    public volatile boolean canceled = false;

    public Producer(BlockingQueue storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        int num = 0;
        try {
            while (num <= 100000 && !canceled) {

                if (num % 100 == 0) {
                    storage.put(num);
                    System.out.println(num + "Is a multiple of 100.");
                }
                num++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Producer end run");
        }
    }
}

class Consumer {
    BlockingQueue storage;

    public Consumer(BlockingQueue storage) {
        this.storage = storage;
    }

    public boolean needMoreNums() {
        return Math.random() <= 0.95;
    }
}

Analysis of important functions related to stopping threads

  1. Interrupt thread
    1. Principle analysis of interrupt method
  2. Determine whether it has been interrupted
    1. static boolean interrupted()
    2. boolean isInterrupted()
    3. For example, note that the target object of Thread.interrupted() is "current thread",

Common interview questions

  1. How to stop a thread
    1. Principle: use interrupt to request and benefit
    2. To stop a thread, the requestor, the stopped party, and the sub method callee should cooperate with each other
    3. Finally, the wrong method: stop/suspend is obsolete, and volatile's Boolean method cannot handle long-term blocking
  2. If you deal with non interruptible blocking (for example, ReentrantLock.lock() or Socket I/O fails to respond to interrupts, how should you stop the thread?)

Posted by zoffi on Fri, 26 Nov 2021 02:06:46 -0800