ScheduledThreadPoolExecutor实时更改任务

时间:2012-01-14 14:27:54

标签: java rmi

我正在使用ScheduledThreadPoolExecutor类来安排每30或60秒运行一次的任务,如下面的代码所示。我希望能够根据th isRmi变量的值“实时”更改要执行的任务,但我似乎无法使其工作。在我的应用程序开始时,变量是根据用户输入设置的,但即使我在程序执行期间更改它,它仍然执行相同的任务。你能救我吗?

   public void execute() {

        ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(3);

        scheduler.scheduleAtFixedRate(new ServPresTimer(player), 0, 30, TimeUnit.SECONDS);

        if (!isRMI) {
            scheduler.scheduleAtFixedRate(new P2PTimer(player), 1, 60, TimeUnit.SECONDS);
        } else {
            scheduler.scheduleAtFixedRate(new RMITimer(player), 1, 60, TimeUnit.SECONDS);
        }
    }

2 个答案:

答案 0 :(得分:1)

不是调度两个不同的任务(P2P和RMI),而是调度单个(P2POrRMI),它基于isRMI变量的值执行P2P任务执行的任务,或执行RMI任务的内容。您应该能够通过委派RMI或P2P来创建此P2POrRMI任务:

public class P2POrRMITimer implements Runnable {
    private Runnable p2p;
    private Runnable rmi;
    private ObjectWhichContainsTheFlag flagContainer;

    public P2POrRMITimer(Runnable p2p, 
                         Runnable rmi, 
                         ObjectWhichContainsTheFlag flagContainer) {
        this.p2p = p2p;
        this.rmi = rmi;
        this.flagContainer = flagContainer;
    }

    @Override
    public void run() {
        if (flagContainer.isRmi()) {
            rmi.run();
        }
        else {
            p2p.run();
        } 
    }
}

...

scheduler.scheduleAtFixedRate(new P2POrRMITimer(new P2PTimer(player),
                                                new RMITimer(player),
                                                this),
                              1, 
                              60, 
                              TimeUnit.SECONDS);

确保正确同步对isRMI的访问,或使其易变,因为它将由一个线程设置,并由另一个线程读取(调度程序线程)

答案 1 :(得分:0)

我怀疑您有一些内存可见性问题,请尝试:

private volatile boolean isRMI;

volatile在这里至关重要。问题是在多线程环境中,对一个线程中的变量所做的更改可能不会立即(或永远!)对其他线程可见。 volatile使所有更改立即显示在每个帖子中。

您也可以使用AtomicBoolean