在我的应用程序中,我有两个线程,分别是 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 完成。那么这是一个正确的方法吗?