@Synchronized
synchronized
做得对:不要暴露你的锁。
Overview
@Synchronized是synchronized方法修饰符的更安全的变体。同样synchronized,注释只能用于静态和实例方法。它的操作类似于synchronized关键字,但它锁定在不同的对象上。关键字锁定this,但注释锁定在名为LOCK。
如果需要,您可以自己创建这些锁。在LOCK领域会当然不会,如果你已经自己原创生成的。您还可以选择锁定另一个字段,方法是将其指定为@Synchronized注释的参数。在此用法变体中,不会自动创建字段,您必须自己显式创建它们,否则将发出错误。
锁定this或您自己的类对象可能会产生不幸的副作用,因为不受您控制的其他代码也可以锁定这些对象,这可能会导致竞争条件和其他讨厌的线程相关错误。
With Lombok
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");
}
}
Vanilla Java
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");
}
}
}
Supported configuration keys:
lombok.synchronized.flagUsage = [warning | error] (default: not set)
Small print
如果LOCK自动生成的,则使用空Object[]数组初始化字段,而不仅仅是new Object()在操作使用中显示此模式的大多数片段。Lombok这样做是因为新对象不可序列化,但0大小的数组是。因此,使用@Synchronized不会阻止您的对象被序列化。
@Synchronized在您的类 中至少有一个方法意味着将有一个锁定字段,但如果您稍后删除所有此类方法,则将不再存在锁定字段。这意味着您的预定serialVersionUID更改。如果您打算通过java的序列化机制长期存储它们,我们建议您始终serialVersionUID在类中添加一个。如果这样做,@Synchronized从方法中删除所有注释将不会破坏序列化。
如果你想知道为什么当你选择你自己的名义为锁定对象不会自动生成一个字段:因为在字段名称,否则让一个错字将导致非常难找的错误!
网友评论