带有时间限制的Runnable

时间:2012-11-09 14:26:23

标签: java multithreading

尝试构建必须在给定时限内结束的Runnable

目前我正在使用java.util.Timer来中断Runnable线程。

TimerRunnable开始后立即启动。

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

2 个答案:

答案 0 :(得分: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 !!");
    }
}

这可以防止打印两种消息。

答案 1 :(得分: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 !!");
        }

    ...