-
Notifications
You must be signed in to change notification settings - Fork 1
@Synchronized
@Synchronized
是 synchronized
方法修饰符的更安全的变体。与 synchronized
类似,该注释只能用于静态和实例方法。它的操作类似于 synchronized
关键字,但它锁定在不同的对象上。synchronized
关键字在 this
锁定,但注解锁定在名为 $lock
的私有字段上。
如果该字段不存在,lombok 则会为你创建该字段。如果注释 一个 static
方法,则注解会锁定名为 $LOCK
的静态字段。
如果需要,你可以自己创建这些锁。如果你已经自己创建了 $lock
和 $LOCK
字段,那么lombok当然不会生成他们。你还可以选择锁定另一个字段,方法是将其指定为 @Synchronized
注解的参数。在此用法变体中,不会自动创建字段,你必须自己显式创建它们,否则将发出错误。
锁定 this
或你自己的类对象会产生不幸的副作用,因为不受你控制的其他代码也可以锁定这些对象,这可能会导致竞争条件和其他讨厌的线程相关的错误.
import lombok.Synchronized;
public class SynchronizedExample {
private final Object readLock = new Object();
@Synchronized
public static void hello() {
System.out.println("world");
}
@Synchronized
public int answerToLife() {
return 42;
}
@Synchronized("readLock")
public void foo() {
System.out.println("bar");
}
}
public class SynchronizedExample {
private static final Object $LOCK = new Object[0];
private final Object $lock = new Object[0];
private final Object readLock = new Object();
public static void hello() {
synchronized($LOCK) {
System.out.println("world");
}
}
public int answerToLife() {
synchronized($lock) {
return 42;
}
}
public void foo() {
synchronized(readLock) {
System.out.println("bar");
}
}
}
lombok.synchronized.flagUsage
= [ warning
| error
](默认:未设置)
如果已配置,Lombok 会将 @Synchronized
的任何用法标记为警告或错误。
如果自动生成 $lock
和/或 $LOCK
,则使用空的 Object[]
数组初始化字段,而不仅仅是一个 new Object()
,正如大多数片段在操作中显示此模式。 Lombok 这样做是因为new Object() 不可序列化,但是大小为0的数组可以序列化。因此,使用 @Synchronized
不会阻止对象序列化。
在类中至少有一个 @Synchronized
方法意味着会有一个锁定字段,但是如果稍后删除所有这些方法,则不再有锁定字段。这意味着你预定的 serialVersionUID
会发生变化。如果你打算通过java的序列化机制长期存储它们,我们建议您始终在你的类中添加 serialVersionUID
。如果这样做,从方法中删除所有 @Synchronized
注解将不会破坏序列化。
如果你想知道为什么在为锁定对象选择自己的名称时不会自动生成字段:因为如果这么做了,在字段名称中输入错误将导致很难找到错误!