1

我正在尝试通过ScheduledExecutorService. 因此,我创建了一个从网站加载数据的生产者工作线程和过滤此数据的消费者线程。这是演示我的问题的代码片段:

public void RunPeriodicBackgroundTasks() {
  private final ScheduledExecutorService backgroundTaskExecutor_ = Executors.newScheduledThreadPool(2);
backgroundTaskExecutor_.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
   LinkedHashMap<String, Object> result_ = new LinkedHashMap<String, Object>(lowLevelNetworkOperation_.executeServerCommand(DASHBOARD_INBOX_SENT_COMMAND, params)); 
    }
},1 ,3, SECONDS);
    //AND NOW I CREATE ANOTHER THREAD for the second task
   backgroundTaskExecutor_.scheduleAtFixedRate(new Runnable() {

    @Override
    public void run() {
        //HERE I WANT To USE result_

    }
}, 1,3, SECONDS);
    }
4

1 回答 1

2

您可以在此处使用 ConcurrentLinkedQueue。

在你的第run一种方法中。

private final ConcurrentLinkedQueue<Map.Entry<String,Object>> queue = new ConcurrentLinkedQueue<Map.Entry<String,Object>>();
public void run(){
   LinkedHashMap<String, Object> result_ = new LinkedHashMap<String, Object>(lowLevelNetworkOperation_.executeServerCommand(DASHBOARD_INBOX_SENT_COMMAND, params)); 

   for(Map.Entry<String,Object> entry: result_.entrySet()){
      queue.offer(entry);
   }
}

在你的另一场比赛中

public void run(){
   List<Map.Entry> currentEntries = new ArrayList<Map.Entry>();
   Map.Entry  entry = null;
   while((entry = queue.poll())!=null){
       currentEntries.add(entry);
   }
   //use it now
}

现在您会注意到这违反了生产者/消费者模式,因为您的两个线程是按固定速率安排的。这意味着它会一遍又一遍地定期唤醒/运行/睡眠。ConcurrentLinkedQueue 不会阻塞,因此如果 Queue 中没有元素,它将返回 null。

如果您希望它成为真正的生产者/消费者,您将改为安排第一个任务,但第二个任务将等待队列信号唤醒。

final BlockingQueue<Map.Entry>queue = new LinkedBlockingQueue<Map.Entry>();

//This is your second run
public void run(){
    while(!Thread.currentThread().isInterrupted()){
        Map.Entry current = queue.take(); //suspend here if the queue is empty until it 1 or more elements
        //use current
    }
}
于 2013-02-20T19:55:32.097 回答