gpt4 book ai didi

java - 我怎样才能访问这个列表并且也是线程安全的?

转载 作者:行者123 更新时间:2023-12-01 18:04:33 24 4
gpt4 key购买 nike

我的主线程产生了 2 个线程,它们都需要访问同一个列表。我不确定最好的方法是什么。这是我所拥有的,但我仍然遇到并发修改异常。

class Parent {
private List<String> data;

public List<String> getData() {
return data;
}

public static void main(String args[]) {
Parent p = new Parent();
p.start();
}

public void start() {
Thread a = new Thread(new A(this)).start();
Thread b = new Thread(new B(this)).start();
}

public A implements Runnable {
private Parent parent;

public A(Parent p) {
parent = p;
}

public void run() {
while (true) {
parent.getData().add("data");
}
}
}

public B implements Runnable {
private Parent parent;

public B(Parent p) {
parent = p;
}

public void run() {
Iterator<String> i = parent.getData().iterator();
while(i.hasNext()) {
// do more stuff with i
i.remove();
}
}
}
}

我的A类基本上是数据的生产者,而B是消费者。我接受我以错误的方式处理这件事的可能性。因此,欢迎所有帮助。我只需要能够安全地从一个线程添加到列表并从另一个线程从列表中删除项目。提前致谢。

最佳答案

好吧,对于生产者/消费者,我推荐 LinkedBlockingQueueConcurrentLinkedQueue 。这将处理并发读取和写入(或在本例中为推送/轮询)。

您可能希望您的消费者一直运行,直到向其发送某些关闭条件。如果您使用阻塞队列,这意味着您将需要发送一个排队项目来指示消费者应该停止消费。这将是一个带有关闭功能的阻塞队列实现。

   public enum QueueItemType {
CONSUMABLE,
SHUTDOWN
}

public class QueueItem {
public final QueueItemType type;
public final String payload;

public QueueItem(QueueItemType type, String payload) {
this.type = type;
this.payload = payload;
}
}

public class B implements Runnable {
private Parent parent;

public B(Parent p) {
parent = p;
}

public void run() {
while(true) {
QueueItem data = parent.getData().poll();
if (data.type == QueueItemType.SHUTDOWN) {
break;
} else {
// do more stuff with data.payload
}
}
}
}

请注意,阻塞队列的 poll 结果没有空检查。这是因为,根据定义,阻塞队列会阻塞正在运行的线程,直到有东西出现为止。

如果您希望拥有一个不与生产者竞争的消费者,那么您将需要定期轮询并 sleep 消费者线程。下面是一个使用 ConcurrentLinkedQueue 的示例:

   public class B implements Runnable {
private Parent parent;

public B(Parent p) {
parent = p;
}

public void run() {
while(parent.isStillRunning()) {
String data = parent.getData().poll();
if (data != null) {
// do more stuff with data
} else {
Thread.sleep(10 /*10 ms, but you can make this whatever poll interval you want*/);
}
}
}
}

关于java - 我怎样才能访问这个列表并且也是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37713660/

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