gpt4 book ai didi

java - 通过参数同步 Java 方法

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

假设我们有一个方法 doSomething(String input) 并且我们希望通过不同的输入同步运行它。

这意味着运行 doSomething(A) 应该阻止 doSomething(A) 的任何连续调用,直到第一个调用完成但不应该阻止 doSomething( B)doSomething(C)

所以我创建了一个包装方法来实现这个目标。它根据输入值创建对象并锁定它们,并在列表中保留对它们的引用。

private static final ArrayList<String> runningTasks  = new ArrayList<>();


public void doSomethingSyncedByInput(String input) {

// Create a lock or load an already created lock from the list.
// (Yeah, it's a race condition but forget about it. It's just an example.)
String lock = new String(input);
if(runningTasks.contains(input)){
// get currently available lock object
lock = runningTasks.get(runningTasks.indexOf(input));
}else {
// add a reference on tasks list
runningTasks.add(lock);
}

synchronized (lock) {
doSomething(input);
}
}

它确实有效;但它不是一个完全线程安全的解决方案,因为 ArrayList 不是线程安全的。 ArrayList 的内容不是易变的,根据文档,添加和删除列表中的项目不会立即反射(reflect)在其他线程上。

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.

ArrayList 的一个众所周知的线程安全变体是 CopyOnWriteArrayList(它复制元素并重新设置内部 volatile 字段保持元素以确保在所有其他线程上立即拥有最新版本的列表)。顾名思义,它在向列表中添加新项目时复制每个列表项目,这意味着对获得锁定的实际对象的引用将丢失,并且代码将被打破。

所以我需要一个数据类型,它包含一个对象列表并且不复制或更改对象以支持并发。我可以使用 String.intern() 功能,但它会带来很多潜在问题,尤其是在移动平台上。

有什么想法吗?

或者,您知道任何可用的防弹实现吗?

顺便说一句,我在 Android 平台上。

更新:

我自己找到了解决方案。看看我自己的答案。欢迎提出意见。

最佳答案

您不需要数据类型。您需要一个专用于锁定代码的信号量。在检查包含之前获取信号量。弄清楚你是否在列表中。如果需要,将您自己添加到列表中。之后释放它。您现在可以通过同步方式获取任何锁。

(这基本上也是任何同步类型都会做的——除了你自己做信号量,你可以一次同步多个操作,比如检查包含然后添加到列表。使用同步数据类型是一个常见的错误,期望它会解决您的问题,却发现您需要在更高级别围绕多个功能进行同步)。

当然,您的代码还有其他弱点。您永远不会在列表完成时从列表中删除旧 key ,因此您可以在那里拥有无限大小。列表中还包含一个 N 操作,如果您更关心速度而不是内存,则 HashMap 更好。

关于java - 通过参数同步 Java 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50088579/

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