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 回答