I have a Singleton class which is a thread safe, do I need to lock it methods?
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;
}
do I need to lock each method like this to ensure thread safety?
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);
}
CodePudding user response:
The best performing and thread-safe Singleton implementation is the William Pugh Singleton. You don't need synchronized blocks and ReentrantReadWriteLock
.
The following implementation ensures multi-thread safety and the best performances as the nested static class is loaded by the class loader only when the method getInstance()
is invoked. In fact, a static nested class is simply a static member of the outer class (no difference from a static field or a static method in terms of creation time). The static member is created only when the class is used, so since no instances of the JsonWriter
can be created with a constructor, a single thread-safe instance is generated only when the outer class is used via the getInstance()
method.
Your implementation could look like this:
class JsonWriter {
private JsonWriter() {}
public static JsonWriter getInstance() {
return SingletonHelper.INSTANCE;
}
private static class SingletonHelper {
private static final JsonWriter INSTANCE = new JsonWriter();
}
}
CodePudding user response:
1 Please dont use synchronized and Lock in one class
2 If you want to use synchronized:
private static volatile JsonWriter instance;
private JsonWriter() {
}
public synchronized static JsonWriter getInstance() {
JsonWriter result = instance;
if (result == null) {
instance = new JsonWriter();
}
return result;
}
3 Or you can use Locks:
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;
}