Java shutdown hooks

Using IntelliJ IDE, java 1.8, lang level 6 in the IDE (and all that is used by default on the command line).

Compiling and starting from the command line (Windows 7) using

javac -cp . Main.java
java -cp . Main

Given the following code, what I would like to do is close all running threads in the application (and maybe I don’t need to do this if the OS or JVM does this for me). I have a MyThread thread, which in turn contains a list of threads that it controls (and when the main one is interrupted, it will send an interrupt to each thread in its list).

When I run the code, I get output Keeping busy.every 2 seconds. When I press CTRL-C, it starts the completion hook (I returned println messages there to confirm), but this is all the output that I see. I never see the end Cancelled.nr of the end of main () ... so I must also assume that the Cancel method does not start either.

So, first of all, do I need to take care of this? Am I ok with just looping (mostly) on isInterrupted and terminating the program? How to remove all subtopics?

import java.util.HashMap;

class MyThread extends Thread {}

public class Main
{
    private static volatile boolean running = true;
    // List of active threads.
    private HashMap<String, Thread> threads = new HashMap<String, Thread>();

    public static void main(String[] args) throws InterruptedException
    {
        // Get an instance of the Main class.
        Main myApp = new Main();

        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            public void run()
            {
                running = false;
            }
        });

        // Loop until system shutdown.
        while (running && !Thread.currentThread().isInterrupted())
        {
            myApp.CreateMyThread();

            // In real code, I have a wait() here, rather than the following lines.

            System.out.println("Keeping busy.");
            Thread.sleep(2000);
        }

        System.out.println("Cancelled.");

        // Kill all threads.
        myApp.Cancel();

        System.exit(0);
    }

    private void Cancel()
    {
        for (Thread t : threads.values())
        {
            t.interrupt();
        }
    }

    private void CreateMyThread()
    {
        if (threads.get("mythread") instanceof MyThread)
        {
            // Already exists.
            return;
        }

        MyThread t = new MyThread();
        t.start();
        threads.put("mythread", t);
    }
}

EDIT

, . Threadlist, hashmap, , "synchronized" / . . CancelThreads . : , .. , ?

import java.util.HashMap;

class MyThread extends Thread {}

class Threadlist
{
    // List of threads.
    private HashMap<String, Thread> threads = new HashMap<String, Thread>();

    public synchronized void AddThread(String name, Thread thread)
    {
        threads.put(name, thread);
    }

    public synchronized Thread GetThread(String name)
    {
        return threads.get(name);
    }

    public synchronized void CancelThreads()
    {
        for (Thread t : threads.values())
        {
            System.out.printf("Killing a thread by the name of '%s'\n", t.getName());
            t.interrupt();
        }
    }
}

public class Main
{
    private static volatile boolean running = true;
    // List of active threads.
    private static Threadlist threads = new Threadlist();

    public static void main(String[] args) throws InterruptedException
    {
        // Get an instance of the Main class.
        Main myApp = new Main();

        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            public void run()
            {
                threads.CancelThreads();
                running = false;
            }
        });

        // Loop until system shutdown.
        while (running && !Thread.currentThread().isInterrupted())
        {
            myApp.CreateMyThread();

            // In real code, I have a wait() here, rather than the following lines.

            System.out.println("Keeping busy.");
            Thread.sleep(2000);
        }

        System.out.println("Cancelled.");

        System.exit(0);
    }

    private void CreateMyThread()
    {
        if (threads.GetThread("mythread") instanceof MyThread)
        {
            // Already exists.
            return;
        }

        MyThread t = new MyThread();
        t.start();
        threads.AddThread("mythread", t);

}

}

ShutdownHook, Thread, run(), , main- > , , .

+4
2

, ( , ).

, , , , Thread.join(long) . - .

. , , , (interrupt(), wait()/notifyAll()) java.util.concurrent.

:

    final Object lock = new Object(); //Lock object for synchronization.
    final Thread mainThread = Thread.currentThread(); //Reference to the current thread.

    Runtime.getRuntime().addShutdownHook(new Thread()
    {
        public void run()
        {
            try{
                synchronized(lock){
                  running = false;
                  lock.notifyAll();
                }

                mainThread.join(4000);
            }catch(InterruptedException){
               //Interrupted.
            }
        }
    });

    synchronized(lock){
        while (running && !Thread.currentThread().isInterrupted())
        {
            myApp.CreateMyThread();

            System.out.println("Keeping busy.");
            lock.wait(2000); 
        }
     }

, , wait() (wait() ), , 2 . , .

+1

- , (, ). , , . , , , 2 , , .

.

+4

Source: https://habr.com/ru/post/1545271/


All Articles