java 并发发生在
java concurrency happens before
假设您有 2 个线程共享一个对象数组列表,然后您进入其中一个线程,并通过添加更多对象来更改整个数组列表,
static ArrayList<Object> o =
static Object lock = new Object();
在线程 1 中
o.addAll(another arraylist);
synchronized(lock){}
然后说定期让线程 2 做这样的事情,
synchronized(lock){}
o.get(7);
列表最终会得到正确更新,但它在线程 1 中被更改时访问。这是不允许的还是什么或者它会 运行 正确吗?
未指定行为。理论上,addAll()
的实现方式可以使 o.get(7)
抛出异常、挂起、return 错误值或执行任何其他操作。
使用 ArrayList
悬挂是一个不太可能的选择,但其他结构(例如 HashMap
、LinkedList
、...)就不那么宽容了。
所以基本上你不想依赖"it won't be that bad, will it?"
有一个列表实现,它基本上实现了 "read the old content while changes are made",它是 CopyOnWriteArrayList
。如果您只关心正确的读取,但并不总是需要最新的读取,并且写入远不如读取常见,那么这可能是一个很好的解决方案。
假设您有 2 个线程共享一个对象数组列表,然后您进入其中一个线程,并通过添加更多对象来更改整个数组列表,
static ArrayList<Object> o =
static Object lock = new Object();
在线程 1 中
o.addAll(another arraylist);
synchronized(lock){}
然后说定期让线程 2 做这样的事情,
synchronized(lock){}
o.get(7);
列表最终会得到正确更新,但它在线程 1 中被更改时访问。这是不允许的还是什么或者它会 运行 正确吗?
未指定行为。理论上,addAll()
的实现方式可以使 o.get(7)
抛出异常、挂起、return 错误值或执行任何其他操作。
使用 ArrayList
悬挂是一个不太可能的选择,但其他结构(例如 HashMap
、LinkedList
、...)就不那么宽容了。
所以基本上你不想依赖"it won't be that bad, will it?"
有一个列表实现,它基本上实现了 "read the old content while changes are made",它是 CopyOnWriteArrayList
。如果您只关心正确的读取,但并不总是需要最新的读取,并且写入远不如读取常见,那么这可能是一个很好的解决方案。