私のアプリケーションでは、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 の終了を待機するためです。それで、これは適切なアプローチですか?