线程安全单例,锁
Thread safe singleton, locks
我有一个线程安全的单例class,我需要锁定它的方法吗?
private static volatile JsonWriter instance;
private static final Object mutex = new Object();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private JsonWriter() {
}
public static JsonWriter getInstance() {
JsonWriter result = instance;
if (result == null) {
synchronized (mutex) {
result = instance;
if (result == null) {
instance = result = new JsonWriter();
}
}
}
return result;
}
我是否需要像这样锁定每个方法以确保线程安全?
public void write(String filePath, ArrayNode content) throws IOException {
lock.writeLock().lock();
File file = new File(MASTER_DIR + "/" + filePath);
mapper.writerWithDefaultPrettyPrinter().writeValue(Files.newOutputStream(file.toPath()), content);
}
1 请不要同时使用 synchronized 和 Lock class
2 如果要使用同步:
private static volatile JsonWriter instance;
private JsonWriter() {
}
public synchronized static JsonWriter getInstance() {
JsonWriter result = instance;
if (result == null) {
instance = new JsonWriter();
}
return result;
}
3 或者你可以使用锁:
private static volatile JsonWriter instance;
private static final Object mutex = new Object();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private JsonWriter() {}
public static JsonWriter getInstance() {
lock.writeLock().lock();
JsonWriter result = instance;
if (result == null) {
instance = result = new JsonWriter();
}
lock.writeLock().unlock();
return result;
}
性能最佳且 thread-safe 的单例实现是 William Pugh Singleton。您不需要同步块和 ReentrantReadWriteLock
.
William Pugh 实施确保了 multi-thread 安全和最佳性能,因为它避免了急于创建。事实上,在 class 级别初始化的静态成员 INSTANCE 只会在 class 加载程序加载嵌套 class 时创建,即当嵌套 class 将被实际使用。在下面的实现中,这只会在调用 getInstance()
方法时发生。事实上,与 EagerSingleton 相反,该模型实际上允许使用封闭的 class 而不会导致急切实例化。这意味着可以安全地使用封闭 class 提供的任何其他方法而无需初始化 INSTANCE
;只有 getInstance()
方法会导致它。
您的实施可能如下所示:
class JsonWriter {
private JsonWriter() {}
/* ... other methods ... */
public static JsonWriter getInstance() {
return SingletonHelper.INSTANCE;
}
private static class SingletonHelper {
private static final JsonWriter INSTANCE = new JsonWriter();
}
}
特别感谢@Holger,他在评论中做出了重要的澄清和评论。
我有一个线程安全的单例class,我需要锁定它的方法吗?
private static volatile JsonWriter instance;
private static final Object mutex = new Object();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private JsonWriter() {
}
public static JsonWriter getInstance() {
JsonWriter result = instance;
if (result == null) {
synchronized (mutex) {
result = instance;
if (result == null) {
instance = result = new JsonWriter();
}
}
}
return result;
}
我是否需要像这样锁定每个方法以确保线程安全?
public void write(String filePath, ArrayNode content) throws IOException {
lock.writeLock().lock();
File file = new File(MASTER_DIR + "/" + filePath);
mapper.writerWithDefaultPrettyPrinter().writeValue(Files.newOutputStream(file.toPath()), content);
}
1 请不要同时使用 synchronized 和 Lock class
2 如果要使用同步:
private static volatile JsonWriter instance;
private JsonWriter() {
}
public synchronized static JsonWriter getInstance() {
JsonWriter result = instance;
if (result == null) {
instance = new JsonWriter();
}
return result;
}
3 或者你可以使用锁:
private static volatile JsonWriter instance;
private static final Object mutex = new Object();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private JsonWriter() {}
public static JsonWriter getInstance() {
lock.writeLock().lock();
JsonWriter result = instance;
if (result == null) {
instance = result = new JsonWriter();
}
lock.writeLock().unlock();
return result;
}
性能最佳且 thread-safe 的单例实现是 William Pugh Singleton。您不需要同步块和 ReentrantReadWriteLock
.
William Pugh 实施确保了 multi-thread 安全和最佳性能,因为它避免了急于创建。事实上,在 class 级别初始化的静态成员 INSTANCE 只会在 class 加载程序加载嵌套 class 时创建,即当嵌套 class 将被实际使用。在下面的实现中,这只会在调用 getInstance()
方法时发生。事实上,与 EagerSingleton 相反,该模型实际上允许使用封闭的 class 而不会导致急切实例化。这意味着可以安全地使用封闭 class 提供的任何其他方法而无需初始化 INSTANCE
;只有 getInstance()
方法会导致它。
您的实施可能如下所示:
class JsonWriter {
private JsonWriter() {}
/* ... other methods ... */
public static JsonWriter getInstance() {
return SingletonHelper.INSTANCE;
}
private static class SingletonHelper {
private static final JsonWriter INSTANCE = new JsonWriter();
}
}
特别感谢@Holger,他在评论中做出了重要的澄清和评论。