簡體   English   中英

具有Observer模式的Java線程可進行長時間操作

[英]Java Threads with Observer pattern for long operations

在我的應用程序中,我有兩個線程分別為ThreadA和ThreadB。 ThreadA是一個持有並處理某些數據的線程(生產者),而ThreadB是從ThreadA讀取的相應使用者線程(只讀)。
我想實現ThreadB通知ThreadA更新數據(這可能需要一些時間),並且當數據更改時,ThreadB應該從ThreadA獲取/請求它。 只要ThreadA尚未完成數據的更新,ThreadB就不會等待,而是繼續使用他擁有的當前(舊)數據進行工作。 現在我的想法是使用觀察者模式通知ThreadB ThreadA已完成更新

public class ThreadA implements Runnable {

private boolean sometimesTrue = false;
private int[] someBigArray = new int[XXX];


private synchronized int[] getBigArray() {
    return this.someBigArray;
}

private void fireListenerDataChanged() {
    for(ThreadAListener l : listeners) 
        l.notify();
}

private synchronized void updateArray() {
    //do some stuff on the array that takes a lot of time
}

@Override
public void run() {
    while(true) {
        if(sometimesTrue) {
            updateArray();
        }
    }
}


public void doUpdate() {
    this.sometimesTrue = true;
}

}


public class ThreadB implements Runnable, ThreadAListener  {

private int[] bigDataToWorkOn;
private Thread threadA;

public ThreadB(ThreadA threadA) {
    this.threadA = threadA;
}

@Override
public void run() {
        //do my stuff with bigDataToWorkOn 
        if(sometimesTrue) {
            threadA.doUpdate();
        }
}


public void notify() {
    this.bigDataToWorkOn = threadB.getBigArray();
}      

}

我的主要目標是避免使用某種BlockingQueue,因為afaik ThreadB會等他的工作,直到ThreadA傳遞隊列中的數據。 如果我在ThreadB的while循環中調用getBigArray,則會發生相同的問題,因為當ThreadA當前在updateArray中工作時,ThreadA將被鎖定,並且ThreadB也將等待ThreadA完成。 那么這是一種適當的方法嗎?

這種方法可能是可行的解決方案,但事實是,如果您不想在ThreadA run()方法中使用無限循環,則sometimesTrue必須使用volatile修飾符標記ThreadA

此外,如果您不希望ThreadA吃掉100%的單核,則必須在其run()方法內的循環中添加一些延遲:

public void run() {
    try {
        while(true) {
            if(sometimesTrue) {
               updateArray();
            }
            Thread.sleep(100);
        }
    } catch (InterruptedException e) {
      // ... do something with e 
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM