使用 Collections.synchronizedSet 的每个语法

发布于 2024-08-21 17:33:19 字数 651 浏览 5 评论 0原文

问题是这样的。 做了一套

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

〆凄凉。 2024-08-28 17:33:19
  1. 我是否应该包装每个 for 循环... 不,你不需要用同步块包装每个 for 循环,事实上你甚至不应该这样做,因为它带有一个性能惩罚。您只需要包装那些迭代可能由多个线程同时访问的集合的 for 循环。

  2. 我的 IDE (IntelliJ IDEA) 不断报告... 在您的特定情况下,这不是问题,因为如果不同的线程有不同的 s 实例,那么显然迭代器也会不同.

  1. 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.

  2. 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.

对你而言 2024-08-28 17:33:19

该文档清楚地表明您应该面对并发访问时执行此操作。它还提供了您应该执行此操作的一个很好的理由:

面对并发访问,用户在迭代返回的集合时必须手动同步它。原因是迭代是通过对集合的多次调用来完成的,必须将其组合成单个原子操作。以下是迭代包装器同步集合的习惯用法。

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:

In the face of concurrent access, it is imperative that the user manually synchronize on the returned collection when iterating over it. The reason is that iteration is accomplished via multiple calls into the collection, which must be composed into a single atomic operation. The following is the idiom to iterate over a wrapper-synchronized collection.

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

人疚 2024-08-28 17:33:19

由于 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 your Set 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 on s. The use of volatile should help here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文