如何制作一个无法从命令行中删除的Java程序?

时间:2015-07-19 22:14:52

标签: java shutdown-hook

我正在尝试运行一个似乎有#9; 9生命的Java程序"。当我们运行它时,它会在无限循环中打印出以下内容:

GlobalVar = 1
GlobalVar = 1
GlobalVar = 1
/* etc */
GlobalVar = 1
GlobalVar = 1

然后,一旦我们CTRL+C并杀死程序,而不是退出并转到命令提示符......它应该像这样重新继续:

GlobalVar = 2
GlobalVar = 2
GlobalVar = 2

然后,它应该重新打开,GlobalVar设置为3,4,5等。

首先,我知道这段代码有点不切实际 - 它仅适用于学术练习。但我正在学习Java。

到目前为止我的代码:

import java.io.*;
public class SHTest {  

            static int globalVar = 0;

 public static void main ( String[] args ) throws  IOException  , InterruptedException {

        System.out.println ("The Global Var is " + globalVar);
        Runtime.getRuntime ().addShutdownHook ( new Thread () {
            @Override
            public void run () {

            globalVar += 1;
 /* shutdown */
           String[] command = {"C://Program Files//Java//jdk1.7.0_02//bin//java.exe", "SHTest"};  //args[0] ... CreateTexts
           ProcessBuilder pb = new ProcessBuilder(command);
           pb.redirectErrorStream(true);

           try {
               Process exec = pb.start(); 
               BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
               String text = null;
           while ((text = br.readLine()) != null) {
               System.out.println(text);
           }

           System.out.println("Process exited with " + exec.waitFor());
           } 

            catch(IOException io) { }

            catch(InterruptedException inter) { }


            }
        } );  //end addShutdownHook() 

        //int copyGlobalVar = globalVar;
        while ( true  ) {
            System.out.println ( "Looping " + globalVar );
            Thread.sleep ( 800 );
        }
    }


    }

参考:

Capture SIGINT in Java

Why can't I re-execute a Java program from within an Exception block?

addShutdownHook method

注意:我愿意使用Windows批处理文件,因为JVM似乎对这些事情有其自身的局限性。或其他工具。即使对于Linux操作系统,也可以。

2 个答案:

答案 0 :(得分:2)

静态变量globalVar将无法在进程的破坏和重新创建中存活下来。在新进程中,它将重新初始化为0.它应作为参数传递给进程,然后globalVar应初始化为该参数的值。

答案 1 :(得分:1)

在JVM停止程序之前调用

Runtime.getRuntime ().addShutdownHook,但它不会阻止它停止。

如果要拦截SIGINT信号,则需要在Unix和Windows上使用SignalHandler(sun.misc.SignalHandler)。 见this文章(pdf,第8和9页)。

以下是一个如何使用它的简单示例:

Signal.handle(new Signal("INT"), new SignalHandler () {
  public void handle(Signal sig) {
    if (globalVar == 9) {
      System.out.println("9 lifes consumes, program will shutdown");
      System.exit();
    }
    System.out.println(globalVar + " lifes consumed, one more will be consumed");
    // increment your score here
  }
});

来源:this post.