Java中的线程安全Enumset

3
我使用以下代码来初始化一个同步的EnumSet实例:
private final Set<MyClass> instance = Collections.synchronizedSet(EnumSet.noneOf(MyClass.class));

我有两个问题:

  • 在这种情况下,我是否保留EnumSet的所有好处,如紧凑性和效率?
  • 是否有更...嗯...语义丰富的方法来获取一个空的并且同步的EnumSet实例?

我觉得没问题。Collections.synchronizedSet只是一个包装器,不会改变EnumSet或替换它。 - Peter Lawrey
我刚刚检查了源代码 - 确实只是一个包装器,它添加了基于互斥锁的同步。而且似乎没有任何库提供更易读的一行代码。 - jilt3d
1个回答

8
根据javadoc,如果多个线程同时访问一个枚举集合并且至少有一个线程修改了该集合,那么它应该在外部进行同步。通常通过在自然封装枚举集合的某个对象上进行同步来实现。如果不存在这样的对象,则应使用Collections.synchronizedSet(java.util.Set)方法“包装”该集合。为了防止意外的非同步访问,最好在创建时完成此操作:
``` Set s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class)); ```
所以我认为这是你能做的最好的事情。
我也会像你一样将Set final化。很奇怪他们在javadoc中没有提到它。
编辑:回答第一个问题,简短的回答是是的,长的回答是是的,但您必须付出额外的同步代价。

谢谢,我查看了EnumSetCollections的javadoc,但没有找到答案。不过,查看源代码回答了第一个问题。关于第二个问题 - 我希望Guava提供这样的方法,但似乎没有。 - jilt3d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接