如何制作无法从命令行终止的 Java 程序?
How to make a Java program that cannot be killed from command line?
我正在尝试 运行 一个 Java 似乎有“9 条命”的程序。当我们 运行 它时,它只是在无限循环中打印出以下内容:
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
注意:我愿意使用 windows 批处理文件,因为 JVM 似乎对这些东西有其自身的限制。或者其他工具。即使对于 Linux OS ,也可以
Runtime.getRuntime ().addShutdownHook
在 JVM 停止程序之前调用,但不会阻止程序停止。
如果你想拦截 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.
静态变量 globalVar
将无法在进程的破坏和重建中幸存下来。在新进程中,它将被重新初始化为 0。它应该作为参数传递给进程,然后 globalVar
应该被初始化为该参数的值。
我正在尝试 运行 一个 Java 似乎有“9 条命”的程序。当我们 运行 它时,它只是在无限循环中打印出以下内容:
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
注意:我愿意使用 windows 批处理文件,因为 JVM 似乎对这些东西有其自身的限制。或者其他工具。即使对于 Linux OS ,也可以
Runtime.getRuntime ().addShutdownHook
在 JVM 停止程序之前调用,但不会阻止程序停止。
如果你想拦截 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.
静态变量 globalVar
将无法在进程的破坏和重建中幸存下来。在新进程中,它将被重新初始化为 0。它应该作为参数传递给进程,然后 globalVar
应该被初始化为该参数的值。