4

与えられた制限時間内に終了Runnableなければならないを構築しようとしています。

現在、スレッドjava.util.Timerを中断するために使用しています。Runnable

Timer開始直後にRunnable開始します。

import java.util.Timer;
import java.util.TimerTask;

public class test {
    Thread task;
    Timer  timer;

    public void start(){

        task = new Thread(new worker());
        timer = new Timer("timer",true);

        task.start();
        timer.schedule(new Terminator(),1000*2);
    }


    class worker implements Runnable{
        @Override
        public void run() {

            for (int i = 0 ; i < 2; i++){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("Test Interrupted !!");
                    return;
                }
            }

            System.out.println("Test Finished !!");
            timer.cancel();
        }
    }

    class Terminator extends TimerTask{
        @Override
        public void run() {
            task.interrupt();
            System.out.println("Test Terminated !!");
        }
    }
}

しかし、これによりTimerRunnableスレッド 間の競合状態が発生する可能性があります。Runnable完了間近であり、Timer起動もしています。

これにより、両方が終了する可能性があります。終了しました!! 印刷されていますか?もしそうなら、どのようにそれを回避しますか?

アップデート:

それは起こります:

11-09 21:14:40.741: INFO/System.out(31442): Test Finished !! 18
11-09 21:14:40.751: INFO/System.out(31442): Test Terminated !! 18
11-09 21:14:40.751: INFO/System.out(31442): Test Finished !! 19
11-09 21:14:40.751: INFO/System.out(31442): Test Terminated !! 19
4

2 に答える 2

4

これにより、両方が終了する可能性があります。と終了しました!! 印刷されていますか?

はい。「終了しました」というメッセージが表示されると、キャンセルされる前にタイマーが起動する可能性があります。

System.out.println("Finished !!");
// The timer can fire here.
timer.cancel(); 

これが発生した場合、両方のメッセージが出力されます。


この問題を回避するには、同期を使用できます。

synchronized (someObject) {
    if (!finished) {
        finished = true;
        System.out.println("Finished !!");
        timer.cancel(); 
    }
}

そしてターミネーターで:

synchronized (someObject) {
    if (!finished) {
        finished = true;
        task.interrupt();
        System.out.println("Test Terminated !!");
    }
}

これにより、両方のメッセージフォームが印刷されなくなります。

于 2012-11-09T14:30:17.140 に答える
4

はい。それを避けたい場合はsynchronize、共有ロック オブジェクトを使用する必要があります。

public class test {
    private Object lock = new Object();
    ...

        synchronized(lock) {
            System.out.println("Test Finished !!");
            timer.cancel();
        }
    ...

        synchronized(lock) {
            if( ! task.isRunning() ) return;

            task.interrupt();
            System.out.println("Test Terminated !!");
        }

    ...
于 2012-11-09T14:31:59.700 に答える