Как остановить процесс Java корректно?

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

86
задан Lii 2 June 2015 в 11:45
поделиться

6 ответов

Рычаги завершения работы выполняются во всех случаях, где VM насильственно не уничтожается. Так, если необходимо было выпустить "стандартное" уничтожение (SIGTERM от команды уничтожения) тогда, они выполнятся. Точно так же они выполнятся после вызова System.exit(int).

Однако твердое уничтожение (kill -9 или kill -SIGKILL) тогда они не выполнятся. Так же (и очевидно) они не выполнятся, если Вы вытянете питание от компьютера, бросите его в чан кипящей лавы или победите ЦП в части с кувалдой. Вы, вероятно, уже знали это, все же.

Финализаторы действительно должны работать также, но лучше не полагаться на это для очистки завершения работы, а скорее полагаться на Ваши рычаги завершения работы для остановки вещей чисто. И, как всегда, быть осторожным с мертвыми блокировками (я видел, что слишком много рычагов завершения работы подвешивают весь процесс)!

80
ответ дан blalasaadri 24 November 2019 в 08:05
поделиться

Хорошо, после всех возможностей я принял решение работать с "Контролем Java и управлением"
, Обзор здесь
, Который позволяет Вам управлять одним приложением от другого относительно простым способом. Можно назвать приложение управления из сценария для остановки управляемого приложения корректно прежде, чем уничтожить его.

Вот упрощенный код:

Управляемое приложение:
выполняет его со следующими параметрами VM:
приложение Управления-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

//ThreadMonitorMBean.java
public interface ThreadMonitorMBean
{
String getName();
void start();
void stop();
boolean isRunning();
}

// ThreadMonitor.java
public class ThreadMonitor implements ThreadMonitorMBean
{
private Thread m_thrd = null;

public ThreadMonitor(Thread thrd)
{
    m_thrd = thrd;
}

@Override
public String getName()
{
    return "JMX Controlled App";
}

@Override
public void start()
{
    // TODO: start application here
    System.out.println("remote start called");
}

@Override
public void stop()
{
    // TODO: stop application here
    System.out.println("remote stop called");

    m_thrd.interrupt();
}

public boolean isRunning()
{
    return Thread.currentThread().isAlive();
}

public static void main(String[] args)
{
    try
    {
        System.out.println("JMX started");

        ThreadMonitorMBean monitor = new ThreadMonitor(Thread.currentThread());

        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        ObjectName name = new ObjectName("com.example:type=ThreadMonitor");

        server.registerMBean(monitor, name);

        while(!Thread.interrupted())
        {
            // loop until interrupted
            System.out.println(".");
            try 
            {
                Thread.sleep(1000);
            } 
            catch(InterruptedException ex) 
            {
                Thread.currentThread().interrupt();
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        // TODO: some final clean up could be here also
        System.out.println("JMX stopped");
    }
}
}

:
выполняет его с , остановка или запускается как параметр командной строки

public class ThreadMonitorConsole
{

public static void main(String[] args)
{
    try
    {   
        // connecting to JMX
        System.out.println("Connect to JMX service.");
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        // Construct proxy for the the MBean object
        ObjectName mbeanName = new ObjectName("com.example:type=ThreadMonitor");
        ThreadMonitorMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ThreadMonitorMBean.class, true);

        System.out.println("Connected to: "+mbeanProxy.getName()+", the app is "+(mbeanProxy.isRunning() ? "" : "not ")+"running");

        // parse command line arguments
        if(args[0].equalsIgnoreCase("start"))
        {
            System.out.println("Invoke \"start\" method");
            mbeanProxy.start();
        }
        else if(args[0].equalsIgnoreCase("stop"))
        {
            System.out.println("Invoke \"stop\" method");
            mbeanProxy.stop();
        }

        // clean up and exit
        jmxc.close();
        System.out.println("Done.");    
    }
    catch(Exception e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}


Вот именно.:-)

47
ответ дан Ma99uS 24 November 2019 в 08:05
поделиться

Подобный Вопрос Здесь

Финализаторы в Java плох. Они добавляют много издержек к сборке "мусора". Избегайте их, когда это возможно.

shutdownHook только назовут, когда VM закроется. Я думаю, что это очень хорошо может сделать то, что Вы хотите.

2
ответ дан Community 24 November 2019 в 08:05
поделиться

Передача сигналов в Linux может быть сделана с "уничтожением" (человек уничтожают для доступных сигналов), Вам был бы нужен идентификатор процесса, чтобы сделать это. (топор PS | grep Java) или что-то как этот или хранилище идентификатор процесса, когда процесс создается (это используется в большинстве файлов запуска Linux, видит/etc/init.d)

, Портативная передача сигналов может быть сделана путем интеграции SocketServer в JAVA-приложении. Дело не в этом трудный и дает Вам свободу отправить любую команду, которую Вы хотите.

, Если Вы имели в виду наконец пункты в земельном участке финализаторов; они не получают extecuted, когда System.exit () называют. Финализаторы должны работать, но не должны действительно делать ничего более значительного, но печатать оператор отладки. Они опасны.

0
ответ дан extraneon 24 November 2019 в 08:05
поделиться

Спасибо за Вас ответы. Завершение работы сцепляет швы как что-то, что работало бы в моем случае. Но я также врезался в названный Контроль вещи и бобы управления:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
, Который дает некоторые хорошие возможности для дистанционного мониторинга и управления процессом Java. (Был представлен в Java 5)

0
ответ дан Ma99uS 24 November 2019 в 08:05
поделиться

Другой способ: ваше приложение может открыть серверный сокет и ждать, пока на него поступит информация. Например, строка с «волшебным» словом :), а затем реакция на завершение работы: System.exit (). Вы можете отправить такую ​​информацию в socke с помощью внешнего приложения, такого как telnet.

7
ответ дан 24 November 2019 в 08:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: