1

假设我有一个 Employee 类,我将该类的对象创建为

Employee emp = new Employee();

以下两个同步块有什么区别

synchronized(emp){ } and
synchronized(Employee.class)
4

3 回答 3

8

第一个使用一个 Employee 实例作为监视器。第二个使用Employee 类作为监视器。

如果目标是保护员工的实例变量,那么第一个比第二个更有意义。如果目标是保护 Employee 类的静态变量,那么第二个是有意义的,但不是第一个。

于 2012-05-19T12:23:49.373 回答
1

第一个在类的特定实例上同步。因此,如果您有 2 个线程在该类的两个不同实例上运行,它们可以同时进入块 - 当然是在它们自己的上下文中。

第二个块在类本身上同步。因此,即使您有 2 个线程和两个不同的实例,该块一次也只能由一个线程进入。

于 2012-05-19T12:27:29.243 回答
1

当您同步时,您需要一个对象来定义为信号量。当线程 A 在对象 A 定义的同步块内时,没有其他线程可以在对象 A 定义的其他此类块中,但它可以在其他对象定义的任何其他同步块内。

emp并且Employee.class是不同的对象,因此两个同步块不是不兼容的(您可以在第一个内部有一个线程,在第二个内部有另一个线程)。

在更一般的说明中,您应该使用第一个块来保护仅影响单个员工对象的敏感代码,而在更改一个员工可能会影响其他员工关键部分或它们的集合/聚合值的操作中使用第二个块。

于 2012-05-19T12:27:38.170 回答