1

我試圖通過ScheduledExecutorService在Android中實現生產者 - 消費者模式。所以,我創建了一個生產者工作線程,用於從網站和消費者線程中加載數據以過濾這些數據。這裏是我的問題演示代碼片段:如何在Android的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); 
    } 

回答

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 
    } 
} 
相關問題