0

いくつかのスクリプトを評価する JRuby エンジンがあり、5 秒以上かかる場合はスレッドを閉じたいと考えています。私はこのようなことを試しました:

class myThread extends Thread{
    boolean allDone = false;

    public void threadDone() {
        allDone = true;
    }

    public void run() {
        while(true) {
            engine.eval(myScript);
            if(allDone)
                return;
        }
    }

(...)

    th1 = new myThread();
    th1.start();
    try {
        Thread.sleep(5000);
        if(th1.isAlive())
            th1.threadDone();
    } catch(InterruptedException e) {}

    if(th1.isAlive())
        System.out.println("Still alive");

th1.stop()orを使用してスレッドを強制終了しようとしましth1.interrupt()たが、メソッドによって返される値th1.isAlive()は常にtrueです。

私に何ができる?myScript が "while(1) do; end" になる可能性があることを付け加えたいと思いますが、それが完了するまで待ちきれません。そのため、そのようなスクリプトを防止し、5 秒以上かかる場合はスレッドを強制終了したいと考えています。

4

2 に答える 2

2

別の解決策は、組み込みメカニズムを使用してスレッドを中断することです。

public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        engine.eval(myScript);
    }
}

...
th1 = new myThread();
th1.start();
try {
    Thread.sleep(5000);
    th1.interrupt();
} 

このように、allDoneフィールドは必要なく、同期に失敗するリスクもありません。

于 2012-07-23T12:02:16.267 に答える
0

スレッドを停止可能にするには、次のようなものが必要になる場合があります。

class MyTask implements Runnable {
    public void run() {
        try {
           engine.eval(myScript);
        } catch(ThreadDeath e) {
           engine = null; // sudden death.
        }
    }    
}

Thread.stop() を呼び出すこともできますが、最初にこのメソッドに関する警告を読むことをお勧めします。


スレッドを最大 5 秒間実行したい場合、最も簡単な解決策は、スレッド自体を停止することです。

class MyTask implements Runnable {
    public void run() {
        long start = System.currentTimeMillis();
        do {
           engine.eval(myScript);
        } while(System.currentTimeMillis() < start + 5000);
    }    
}

これは、engine.eval() を繰り返し実行することを前提としています。そうでない場合は、スレッドを stop() する必要があります。正当な理由で廃止されましたが、それが唯一の選択肢かもしれません。

于 2012-07-23T12:49:14.030 に答える