007 Graceful shutdown of threads

I. Overview

 There was another stop method in the jdk that can close the thread, but that method has thread safety problems and has now been abolished.

There is no way to close the thread after that.

But in our use process, we need to close the thread. At this time, we need to use other methods to complete the thread closing operation.


 

2. Complete with marker bits

public  class StopThread {

    private static class task implements Runnable {
        // 标记位
        private volatile boolean flag = true;

        public void run() {
            while (flag) {
                System.out.println("running ...");
            }
        }

        public void shutdown() {
            this.flag = false;
        }
    }

    public static void main(String[] args) throws Exception {
        task task = new task();
        Thread thread = new Thread(task);
        thread.start();
        // Modify the flag bit after the main thread sleeps for three seconds 
        TimeUnit.SECONDS.sleep( 3 );
        task.shutdown();
    }
}

The above method can complete the task, but it needs to constantly monitor the flag bit.


 

3. How to use interrupt

public class InterruptThread {

    private static class Task implements Runnable {
        public void run() {
            try {
                for (;;) {
                    TimeUnit.MICROSECONDS.sleep(100);
                    System.out.println("thread is running ... ");
                }
            } catch (Exception e) {
                return ; 
            }

        }
    }

    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new Task());
        thread.start();
        // After the main thread sleeps for 3 seconds, it actively interrupts the task thread 
        TimeUnit.SECONDS.sleep( 3 );
        thread.interrupt();
    }
}

After the main thread sleeps for 3 seconds, the child thread is actively interrupted, and the sleep method of the child thread will throw an exception. We can terminate the running of the thread by catching the exception.

Here we use the sleep method, and we can also use the judgment method.

public class InterruptThread {

    private static class Task implements Runnable {
        public void run() {
            for (;;) {
                // TimeUnit.MICROSECONDS.sleep(100);
                if (!Thread.interrupted())
                    System.out.println("thread is running ... ");
                else
                    return;
            }

        }
    }

    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new Task());
        thread.start();
        // After the main thread sleeps for 3 seconds, it actively interrupts the task thread 
        TimeUnit.SECONDS.sleep( 3 );
        thread.interrupt();
    }
}

Relatively speaking, the way we use judgment is still better.


 

4. Violently stop the thread

When our task takes a long time and our loop judgment is not triggered at all, at this time we need to use violence to force the thread to stop.

public  class ThreadService {
     // Execution thread, equivalent to a main thread... 
    private Thread executeThread;

    public  void startThread(final Runnable task) {
         // Create an execution thread, this thread is a main thread 
        executeThread = new Thread() {
            @Override
            public  void run() {
                 // Start child thread 
                Thread childThread = new Thread(task);
                 // Set child thread as daemon process 
                childThread.setDaemon( true );
                 // Start child thread task 
                childThread.start();
                 // The parent thread has a linear loop 
                try {
                     // The main thread keeps letting the child thread run 
                    childThread.join();
                    
                } catch (InterruptedException e) {
                     // When the main thread is interrupted, directly terminate its own operation
                     // nothing to do 
                    System. out .println( " Received a signal to terminate the main thread, now I need to stop " ) ;System.out 
                    .println ( " The daemon thread I brought also needs to be terminated.. " );
                     return ; // The main thread is terminated, and the child thread is killed 
                }
            }
        };
        // Open the execution thread 
        executeThread.start();
    }

    public  void shutdown() {
         // Interrupt the main thread--then the daemon is terminated 
        this .executeThread.interrupt();
    }
}

 

We created a thread service class, this service class consists of two methods

[1] Start a thread

[2] Terminate a thread

Principle: There is an execution thread in this thread class, and the thread task will be initialized when it is started. This thread task is very simple.

    [1] Create a child thread and hand over the thread logic to the child thread. The child thread is set as a daemon thread.

    [2] Then the main thread blocks itself until the child thread runs to completion or its own blocking is interrupted.

The implementation of our shutdown method is very simple, that is, it directly interrupts the blocking state of the execution thread. Once the execution of the wise minister is interrupted, it will enter the catch statement, which will terminate the function, and the child thread will also be terminated.


 

5. Summary

Now we see that the end of the thread still needs to encapsulate a service by ourselves, and later we can see the great god

Ligou's code to see how it solves this kind of problem.

This is just to practice the API.    

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325118358&siteId=291194637