我正在使用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);
}
}
答案 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
。