1

Я пытаюсь реализовать шаблон производителя-потребителя в Android через ScheduledExecutorService. Итак, я создал рабочий поток производителя, который загружает данные с веб-сайта и потребительского потока, который фильтрует эти данные. Вот фрагмент кода для демонстрации моей проблемы:Как передать данные между двумя потоками, созданными ScheduledExecutorService в Android?

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

ответ

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 не блокирует, поэтому, если в очереди нет элементов, он возвращает 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 
    } 
} 
Смежные вопросы