2012-01-14 2 views
0

Я использую класс ScheduledThreadPoolExecutor, чтобы запланировать выполнение задач каждые 30 или 60 секунд, как показано ниже. Я хочу иметь возможность изменить задачу, которая будет выполняться в «реальном времени», на основе значения переменной isRmi, но я не могу заставить ее работать. В начале моего приложения переменная устанавливается на основе пользовательского ввода, но даже если я меняю ее во время выполнения программы, она все равно выполняет ту же задачу. Вы можете мне помочь?ScheduledThreadPoolExecutor меняет задачи в реальном времени

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); 
     } 
    } 
+1

Что такое переменная isRMI и как вы ее манипулируете? –

ответ

1

Вместо планирования двух разных задач (P2P и RMI) планируйте один (P2POrRMI), который на основе значения переменной isRMI выполняет выполнение задачи P2P или выполнение задачи RMI. Вы должны быть в состоянии создать эту задачу P2POrRMI, просто делегируя RMI или P2P:

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, или сделать его неустойчивым, так как она будет установлена ​​одним потоком, и прочитанный другим (поток планировщика)

+0

Можете ли вы, пожалуйста, показать мне пример, пожалуйста? – DaveQuinn

+0

@PMMP: Я сделал это. –

+0

Большое спасибо, это сработало :) Кстати, изменение не мгновенное, так? Это займет 60 секунд. – DaveQuinn

0

Я подозреваю, что у вас есть некоторые проблемы видимости памяти, попробуйте:

private volatile boolean isRMI; 

volatile имеет решающее значение здесь. Проблема в том, что в многопоточной среде изменения, внесенные в переменную в одном потоке, могут быть не сразу (или никогда!) Видимыми для других потоков. volatile делает все изменения видимыми сразу для каждой темы.

Вы также можете использовать AtomicBoolean.

+0

Я пробовал, но это не сработало, оно все равно выполняет ту же задачу. – DaveQuinn