をIこのクラスの集合をまとめる。比較的シンプル:入力を送信するソケットに接続し、不安定なライブラリを呼び出すセカンダリjvmから出力を取得する1つのRunnable。
3回の試行後に応答が受信されなかった場合、2次jvmが強制終了されます。しかし、それは再開することができます。セカンダリjvmには、ソケットを閉じるexitフックがあります。
class SafetyValve implements Runnable{
PrintWriter out;
BufferedReader in;
Socket s = null;
AtomicBoolean flag;
SafetyValve(AtomicBoolean b){
flag = b;
}
@Override
public void run() {
try {
s = new Socket("localhost", 9000);
out = new PrintWriter(s.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
while (!Thread.currentThread().isInterrupted()){
flag.set(false);
out.print(0);
out.flush();
System.out.print(in.read());
flag.set(true);
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
メイン/コントローラクラス。
class UnYielding{
int i = 0;
int returnInt(){
i++;
if (i > 2)
while(true);
return i;
}
}
class Hook extends Thread{
RunWild rw;
Hook(RunWild wr){
rw = wr;
}
public void run() {
try {
System.out.println("exit...");
System.out.flush();
rw.socket.close();
rw.server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class RunWild {
ServerSocket server;
Socket socket;
RunWild(){
Runtime.getRuntime().addShutdownHook(new Hook(this));
}
public static void main(String[] args){
UnYielding u;
int i;
PrintWriter out;
BufferedReader in;
RunWild rw = new RunWild();
try {
rw.server = new ServerSocket(9000);
rw.socket = rw.server.accept();
out = new PrintWriter(rw.socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(rw.socket.getInputStream()));
u = new UnYielding();
while ((i = in.read()) != -1){
out.print(u.returnInt());
out.flush();
Thread.sleep(10);
System.out.print("waiting...");
System.out.flush();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
私は期待どおりに動作するOS X上1.8に対してこれをテストしている:それは、二次JVMが標準のサーバソケット実装を持っている
public class Switch {
public static void main(String[] args) {
try {
AtomicBoolean flag = new AtomicBoolean(false);
int counter = 0;
ProcessBuilder pb = ...
pb.directory(,,,);
Process p = pb.start();
SafetyValve sv = new SafetyValve(flag);
Thread t = new Thread(sv);
t.start();
while(t.getState() != Thread.State.RUNNABLE){
Thread.sleep(10);
}
while(true){
if (flag.get() == false){
if (++counter == 3){
while(t.getState() != Thread.State.TERMINATED){
p.destroyForcibly();
t.interrupt();
Thread.sleep(10);
}
break;
}
}
else
counter = 0;
Thread.sleep(100);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
制御
のためのThreadクラスを使用しています。この不安定なクラスが必要な場合は、これを行う1つの方法です
hmmm .. http://stackoverflow.com/questions/10853305/how-to-stop-long-duration-execution-task-例えば、無限ループ実行のようなものですが、わかりません。 –
"割り込み中にループチェック状態にする" - そのようなループが存在する場合は、サードパーティのコードにあります。 –
@efekctiveほとんど違いはありません。メソッドを実行可能ファイルにラップすると、 'run(){run3rdParty(); } '' run3rdParty'は決して戻りません。あなたができることはあまりありません:割り込みチェックを挿入すると、実行されません。 – assylias