首页 > 解决方案 > 为什么在子类中同步超类的静态信息无效?

问题描述

我正在阅读 Doug Lea 的“Java 设计原则和模式中的并发编程”。他说:

与每个类关联的静态锁与任何其他类(包括其超类)的静态锁无关。在试图保护超类中声明的静态字段的子类中添加新的静态同步方法是无效的。请改用显式块版本。

为什么无效?为什么显式块版本有效?

标签: javamultithreadingstatic

解决方案


为了保护超类静态字段,您需要一个公共锁。如果您编写修改超类字段的类,而其他人编写影响超类字段的子类,则您希望确保两段代码引用相同的锁。如果它们各自锁定自己的子类,则没有公共锁,它们仍然可以相互干扰。这就是Lea所说的意思

与每个类关联的静态锁与任何其他类(包括其超类)的静态锁无关。

理想情况下,我们希望在定义静态变量的类中执行所需的任何锁定并保持所有内容都被封装。显然,这种理想可能无法实现,子类可能必须定义锁定,但需要有一个共同的策略来使用什么锁定。

如果您使用static synchronizedthen 创建一个方法,它将获取您定义该方法的类的锁。如果您要保护的不是该类而是超类,那不是您想要的,您希望获取声明需要保护的字段的超类的锁。

指定正确超类的方法是使用“显式块语法”,如下所示:

synchronized(Superclass.class) {
    ...
}

推荐阅读