0

私のアプリケーションでは、ThreadA と ThreadB が指定された 2 つのスレッドがあります。ThreadA は、一部のデータを保持および操作するスレッド (プロデューサー) であり、ThreadB は、ThreadA (読み取り専用) から読み取る対応するコンシューマー スレッドです。
ThreadB が ThreadA にデータを更新するように通知し (時間がかかる場合があります)、データが変更されたときに、ThreadB が ThreadA からデータを取得/要求する必要があることを達成したいと考えています。ThreadA がデータの更新を完了していない限り、ThreadB は待機せずに現在の (古い) データで作業を続行する必要があります。ここで私の考えは、オブザーバー パターンを使用して、ThreadA が更新を完了したことを ThreadB に通知することでした。

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 の使用を避けることでした。これは、ThreadA がデータをキューに渡すまで、ThreadB が作業を待機するためです。ThreadB の while ループで getBigArray を呼び出すと、同じ問題が発生します。これは、ThreadA が現在 updateArray で動作しているときに、ThreadA がロックされ、ThreadB も ThreadA の終了を待機するためです。それで、これは適切なアプローチですか?

4

1 に答える 1

0

のメソッド内に無限ループを持たせたくない場合は、フィールドsometimesTrueを修飾子でマークする必要があるという事実を除いて、このアプローチは実行可能な解決策になる可能性があります。volatilerun()ThreadA

ThreadAさらに、シングル コアを 100%消費したくない場合は、run()メソッド内のループに遅延を追加する必要があります。

public void run() {
    try {
        while(true) {
            if(sometimesTrue) {
               updateArray();
            }
            Thread.sleep(100);
        }
    } catch (InterruptedException e) {
      // ... do something with e 
    }
}
于 2013-06-07T13:31:40.977 に答える