gpt4 book ai didi

java - 阻塞直到元素可用

转载 作者:行者123 更新时间:2023-12-02 05:16:11 24 4
gpt4 key购买 nike

我有一个多线程程序,其中一个线程正在读取数据,而其他多个线程正在处理该数据。如果我有一个写入线程连续添加数据 (Example.add()),而其他读取线程顺序读取该数据 (Example.getData(1), Example.getData(2), ...),阻止读取器直到他们请求的索引处的数据可用的最佳方法是什么?

这个问题有点像生产者-消费者,但我不想“消费”数据。

public class Example {
private ArrayList<Integer> data;

public Example() {
data = new ArrayList<Integer>();
}

public int getData(int i) {
// I want to block here until the element
// index i is available.

return data.get(i);
}

public void add(int n) {
data.add(n);
}
}

最佳答案

这似乎是同步线程的合理方法:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

条件链接显示了这样的示例:

class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();

final Object[] items = new Object[100];
int putptr, takeptr, count;

public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}

public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}

请不要根据代码风格来评判我,这是条件中示例的直接副本。

在您的情况下,您可能会考虑使用所有线程都等待的单个锁,该锁在添加新元素时发出信号。这将导致所有线程唤醒并测试它们的元素是否存在。如果没有,他们就会返回等待下一个信号。

如果您希望它们专门等待第 1 个元素,您可以为每个元素保留一个信号,但这似乎有点过分了。

类似于:

public class Example {
private Lock lock = new ReentrantLock();
private Condition update = lock.newCondition();
public Example(data) {
data = new ArrayList<Integer>();
}

public int getData(int i) {
lock.lock();
try {
while (data.get(i) == null) {
update.await();
}
return data.get(i);
} finally {
lock.unlock();
}
}

public void add(int n) {
data.add(n);
update.signal();
}
}

关于java - 阻塞直到元素可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26941294/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com