使用 Collections.synchronizedSet 的每个语法
问题是这样的。 做了一套
Set<User> users = Collections.synchronizedSet(new HashSet<User>())
...
for(User u : users){
//do something with u
}
我现在根据Java文档
。用户必须 手动同步返回的 迭代时排序集或 其任何 subSet、headSet 或 tailSet 意见。
SortedSet s = Collections.synchronizedSortedSet(new HashSortedSet()); ... 同步{ 迭代器 i = s.iterator(); // 必须在同步块中 while (i.hasNext()) foo(i.next()); }
我很确定 for every 语法使用迭代器,但我不确定是否应该用同步块包装每个 for every 循环。
另一件事,我的 IDE (IntelliJ IDEA) 不断报告,在非最终字段上使用同步块不太可能具有有用的语义,因为不同的线程可能是不同的对象,即使在处理同一个对象时也是如此。
The problem is this. I have made a set
Set<User> users = Collections.synchronizedSet(new HashSet<User>())
...
for(User u : users){
//do something with u
}
Now, according to Java documentation.
It is imperative that the user
manually synchronize on the returned
sorted set when iterating over it or
any of its subSet, headSet, or tailSet
views.SortedSet s = Collections.synchronizedSortedSet(new HashSortedSet()); ... synchronized(s) { Iterator i = s.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }
I'm pretty sure that for each syntax uses iterators but I'm unsure whether or not I should wrap every for each loop with a synchronized block.
Another thing, my IDE (IntelliJ IDEA) keeps reporting that using a synchronized block over a field that is not final is unlikely to have useful semantics since different threads might be different objects, even when working on a same object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我是否应该包装每个 for 循环... 不,你不需要用同步块包装每个 for 循环,事实上你甚至不应该这样做,因为它带有一个性能惩罚。您只需要包装那些迭代可能由多个线程同时访问的集合的 for 循环。
我的 IDE (IntelliJ IDEA) 不断报告... 在您的特定情况下,这不是问题,因为如果不同的线程有不同的 s 实例,那么显然迭代器也会不同.
whether or not I should wrap every for loop... No, you don't need to wrap every for loop with a synchronized block, infact you shouldnt even do that because it comes with a performance penalty. You need to wrap only those for loops that iterate over collections that maybe accessed by multiple threads concurrently.
my IDE (IntelliJ IDEA) keeps reporting.... In your particular case, it's not a problem, because if different threads have different instances of s, then obviously the iterators will be different too.
该文档清楚地表明您应该面对并发访问时执行此操作。它还提供了您应该执行此操作的一个很好的理由:
http://java.sun.com/docs/books/ tutorial/collections/implementations/wrapper.html
要了解更多有关“同步块中的最终变量”的信息,请查看以下内容:java 中的 Final 变量和同步块
The documentation states clearly that you should do this in the face of concurrent access. It also provides a good reason why you should do this:
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
To know more having 'the final variable in the synchronized block' , have a look at this: Final variable and synchronized block in java
由于 foreach 在幕后使用迭代器,因此如果您的
Set
在结构上进行了修改,那么在 foreach 的处理过程中您仍然会遇到ConcurrentModificationException
的情况。关于 IDE 提供的警告,如果您重新分配
s
,则不同线程在尝试同步s
时可能会看到不同的对象。使用易失性
在这里应该有所帮助。As the for each uses the Iterator under the covers, you are still subject to a
ConcurrentModificationException
during the processing of a for each if yourSet
is structurally modified.With regard to the warning that your IDE provides, if you are reassigning your
s
, there is a chance that different threads do see different objects when trying to synchronize ons
. The use ofvolatile
should help here.