对Java枚举值的引用是全局的吗?

时间:2012-05-02 10:47:34

标签: java enums synchronization locking

假设我有一个包含多个值的枚举,例如:

public enum Category {
  A, B, C, D;
}

并且想要创建一个锁定机制,以便我们一次只处理每个类别一个项目。我的第一个想法是做这样的事情:

Set categories = new HashSet();
for (Category cat : Category.values() {
  categories.put(cat);
}

然后当我需要锁定时,我会执行以下操作:

synchronized(categories.get(category)) {
  ....
}

这会起作用还是全局引用枚举值,所以如果其他地方的某个其他线程做同样的事情就会相互阻塞?

谢谢!

3 个答案:

答案 0 :(得分:4)

每个枚举值都是singleton。加载枚举类的classloader只存在一个实例。所以,是的,如果两个线程使用枚举值作为锁,它们将使用相同的锁,从而相互阻塞。

旁注:如果您使用有效的编译Java代码,那么您的问题会更清楚。

答案 1 :(得分:3)

只有一个Category.A个实例,因此所有synchronized(Category.A)都会相互阻塞,这就是你对你的设置所做的事情。

您可以使用与您的枚举关联的私有最终EnumMap,用new Object()填充它,确保您不修改地图,并使用与该类别关联的对象作为锁定对于那个类别。这样你就可以确定锁只用在那段代码中。

答案 2 :(得分:0)

您的枚举将在您的项目(包)中显示。 如果您需要在其他地方使用此logick,则需要添加对此项目的引用。