gpt4 book ai didi

java - 多线程环境下 LinkedList clear 和 new LinkedList 的区别

转载 作者:行者123 更新时间:2023-11-29 05:46:32 25 4
gpt4 key购买 nike

为什么这段代码:

public synchronized void update() {
for(T event : eventQueue)
{
processEvent(event);
}
events = eventQueue;
eventQueue = new LinkedList<T>();
}

以不同方式运行此代码:

public synchronized void update() {
for(T event : eventQueue)
{
processEvent(event);
}
events = eventQueue;
eventQueue.clear();
}

第一个版本工作得很好,但第二个版本不行。 eventQueue.clear();导致应用程序不接收任何事件并以 Concurrent Exception 严重崩溃.

我的应用有两个线程。 UI线程和GameLoop线程。 UI 线程将事件添加到 eventQueue像这样:

public synchronized void addEvent(T newEvent) {
eventQueue.add(newEvent);
}

GameLoop 线程调用更新方法来获取 events 的副本(称为 eventQueue ) .

所有代码都可以在这个网站查看:http://entropyinteractive.com/2011/02/game-engine-design-input/

这对我来说有点神秘,因为我认为 eventQueue = new LinkedList<T>();eventQueue.clear();都会导致空的 LinkedList ?我相信它与建立新引用有关(但为什么呢?!)。

最佳答案

因为在这段代码中:

public LinkedList<T> getEvents()
{
return events;
}

您返回的是原始列表,而不是副本。如果您随后 clear() 该列表,您将导致问题,因为您正在从列表中删除内容(更重要的是,更改列表的大小),而另一个线程正在使用它。

请注意,此函数不是同步,因此您甚至无法安全地从中返回一个副本,因为原始列表可能会在您复制它时更改(更改引用为 atomic ,因此在您的 update() 方法中这样做是安全的。

您可以从同步方法返回一个副本,如下所示:

public synchronized LinkedList<T> getEvents()
{
return new LinkedList<T>(events);
}

但这引入了不必要的复制和锁定。这是否重要取决于您是否更关心 defensive coding 或性能要求。我假设他们出于性能原因这样做。

关于java - 多线程环境下 LinkedList<T> clear 和 new LinkedList<T> 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15688367/

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