Home > Blockchain >  Thread safe singleton, locks
Thread safe singleton, locks

Time:06-01

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;
}
  • Related