I was trying to write a singleton class, which will be used for simple cache implementation. I followed a double checked locking pattern for getting the instance where the instance is a volatile member inside the class. It also contains a HashTable for storing the data.
If I am trying to access a value inside the map through a method, should I provide 'synchronized' keyword for blocking concurrent access?. I am asking this question because the UserCache itself is syncronized using double-checked-locking in the getInstance() method
Or is it better to use a ConcurrentHashMap instead of HashTable?
See the code snippet below for more details.
public class UserCache {
private volatile static UserCache instance;
private Hashtable<String, User> users = null;
private UserCache() {
this.users = new Hashtable<String, User>();
}
public static UserCache getInstance() {
if (instance == null) {
synchronized (UserCache.class) {
if (instance == null) {
instance = new UserCache();
}
}
}
return instance;
}
public synchronized User getUser(String userUid) {
return this.users.get(userUid);
}
public synchronized boolean addUser(User user) {
if (isValidUser(user.getUserUid())) {
return false;
}
this.users.put(user.getUserUid(), user);
return true;
}
...
Any advice would be greatly appreciated :)
Thanks in advance
If that is the extent of your class, then a ConcurrentHashMap would work. If you have any additional methods where more than a simple get/put to the map needs to be synchronized, a ReadWriteLock is a good option to allow concurrent reads.
Another alternative to your double checked locking with a volatile static would be to use an inner class:
private static final class DeferredLoader {
static final UserCache INSTANCE = new UserCache();
}
public static UserCache getInstance() {
return DeferredLoader.INSTANCE;
}
This has the advantage of being immutable and still defers the creation of the instance until the getInstance method is called the first time.
If your methods are synchronized I don't see the need for ConcurrentHashMap. Still, I would use Map<,> instead of Hashtable. It's good practice to favor interfaces.
Related
A friend of mine showed me this as his implementation of the singleton pattern. It seems to work fine, from what I've tested so far. I cannot tell why, but referencing "this" as seen below, just seems like bad practice to me.
Is this usage of "this" in the constructor legitimate?
public class Singleton {
private static Singleton unique = null;
private Singleton() { unique = this; }
public static Singleton instance() {
if (unique == null)
new Singleton();
return unique;
}
}
Is there even a significant difference, compared to doing it the usual way:
public class Singleton {
private static Singleton unique = null;
private Singleton() { }
public static Singleton instance() {
if (unique == null)
unique = new Singleton();
return unique;
}
}
I have not been able to find any reasonable answers to my questions.
So, thanks in advance!
Is this usage of "this" in the constructor legitimate?
It would work, but unreasonable and barely readable. It feels more like a code smell.
Is there even a significant difference, compared to doing it the usual way?
Readability and maintainability should always be considered. It'll be harder to mock and/or use this singleton cause its implementation kind of unique.
Also, as pointed out in the comments. None of the examples are thread-safe. Means this is not a true singleton.
If you want a thread-safe singleton with lazy initialization, I'd suggest to implement it as follows:
public class Singleton {
private static Singleton unique = null;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (unique == null) {
unique = new Singleton();
}
return unique;
}
}
You can enhance it by introducing Double check locking:
public static synchronized Singleton getInstance() {
if (unique == null) {
synchronized (Singleton.class) {
if (unique == null) {
unique = new Singleton();
}
}
}
return unique;
}
Additional Info
There are multiple ways of implementing Singleton pattern:
https://www.geeksforgeeks.org/java-singleton-design-pattern-practices-examples/
Case 1:
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {
...
}
}
Case 2:
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
...
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Is the second method the recommended way to implement the Singleton design pattern, because I have never seen the first one in any example for Singleton pattern.
Without going into all the stuff about singletons being an antipattern (but you should read up on it!), the currently best way to make a singleton in Java is to use an enum.
public enum Singleton {
INSTANCE;
}
The reason this is better is because the JVM guarantees that only one instance of the enum (per classloader) will exist at any time. It is thread safe, and you cannot use reflection to create another instance of the singleton.
Enum-values are also lazily instantiated, so you won't create the singleton before you access Singleton.INSTANCE the first time.
The best way to make a singleton is to use Enum.
public enum Foo {
INSTANCE;
}
What is an efficient way to implement a singleton pattern in Java?
In your example, case 1 is more simple, so it's better.
But just wonder what happen if your constructor function is more complicated with some parameters. At this time, you really need some thing like this:
public class Singleton {
private static final Singleton INSTANCE;
private Singleton(string a, string b, string c) {
...
}
public static Singleton getInstance(string a, string b, string c) {
if (INSTANCE != null) { //note in multiple thread env, need add synchronize here.
......
}
return INSTANCE;
}
}
The first process of creating Singleton object created the instance of Singleton class even before it is being used and that is not the best practice to use.
Also the same problem exists in second implementation.
My preferred way of singleton instance creation:
private static final Singleton INSTANCE = null;
public static Singleton getInstance(){
if(INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
Above implementation of Singleton instance creation is okay in single threaded environment but in case of multi-threaded environment two threads may access if block at same time so they will have different instances. This could be solved as below:
private static final Singleton INSTANCE = null;
public static Singleton getInstance(){
if(INSTANCE == null){
synchronized (Singleton.class) {
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
Hope this helps.
This how I implement singleton with enum
import static collections.concurrancy.ConcurrentHashMapInstanceEnum.STAFF;
public enum ConcurrentHashMapInstanceEnum {
STAFF;
private ConcurrentHashMap<Integer,Person> concurrentHashMap = null;
private ConcurrentHashMapInstanceEnum() {
concurrentHashMap = new ConcurrentHashMap(10, 5f, 4);
}
public ConcurrentHashMap getConcurrentHashMap() {
return concurrentHashMap;
}
}
and this is how to reach in a thread...
staffList = STAFF.getConcurrentHashMap()
Yes Obviously the second method is preferred way to implement Sigleton pattern , Inside getInstance() you have to check if instance is already created then return the same and Only create new instance if there is No instance of the class.
Also Make getInstance method as static method.
Is it better to use the double checked locking idiom for a singleton pattern? Or a synchronised method?
ie:
private static volatile ProcessManager singleton = null;
public static ProcessManager getInstance() throws Exception {
if (singleton == null) {
synchronized (MyClass.class) {
if (singleton == null) {
singleton = new ProcessManager();
}
}
}
return singleton;
}
or
private static processManager singleton = null;
public synchronized static processManager getInsatnce() throws Exception {
if(singleton == null) {
singleton = new processManager();
}
return singleton
}
Have the ClassLoader do the job for you :
/*
* This solution takes advantage of the Java memory model's guarantees about class initialization
* to ensure thread safety. Each class can only be loaded once, and it will only be loaded when it
* is needed. That means that the first time getInstance is called, mySingletonServiceLoader
* will be loaded and instance will be created, and since this is controlled by ClassLoaders,
* no additional synchronization is necessary.
*/
public static DocumentService getInstance() {
return mySingletonServiceLoader.INSTANCE;
}
private static class mySingletonServiceLoader {
static DocumentService INSTANCE = new DocumentService();
}
}
Basically, your second option adds no additional guarantee.
You check more often, but concurrent access can still occur between them, so, you're diminishing the probability of two instances occurring, but not eliminating it.
First option.
There is the ability to create multiple versions of the single instance...
in the getInstance() call the instance is checked for null, and then immediately constructed if it is null, and then the instance is returned.
It should be thread safe.
Refer this also.
The first option is correct double-checked locking implementation, but if there is no more public methods in ProcessManager class but getInstance then all you need is
public class ProcessManager {
private static ProcessManager instance;
static {
instance = new ProcessManager();
}
private ProcessManager() {
}
public static ProcessManager getInstance() {
return instance;
}
}
the class will be loaded and initialized on first ProcessManager.getInstance() invocation
If lazy-load is required, I would adhere to the double-check instead of a synchronized method. In the end, the issue is that of volatile vs. synchronized:
Volatile, simply forces all accesses (read or write) to the volatile variable to occur to main memory, effectively keeping the volatile variable out of CPU caches. This can be important for some actions where it is simply required that visibility of the variable be correct and order of accesses is not important.
Once the instance has been initialized, the synchronized block will not be executed (but for race conditions). The only concurrency cost to be paid is that of a single read to the volatile variable.
Note that in Effective Java Bloch says that loading the volatile field in a local variable enhances performance (I understand that is because there are fewer volatile reads)
public static ProcessManager getInstance() throws Exception {
ProcessManager result = singleton;
if (result == null) {
synchronized (MyClass.class) {
result = singleton;
if (result == null) {
singleton = result = new ProcessManager();
}
}
return result;
}
I have a queston regarding double-checked locking.
Consider this example:
public class Singleton {
private static volatile Singleton instance = null;
public static Singleton getInstance() {
if(instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance ;
}
}
As I have understood, the above code is the correct way to make a Singleton class.
However, NetBeans wants me to remove the outer if statement, so it would look like this:
public class Singleton {
private static volatile Singleton instance = null;
public static Singleton getInstance() {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
return instance ;
}
}
The only differece between these two snippets is that in the second example, the code will always get into the synchronized block and in the first it will not. Why would I listen to NetBeans and remove the outer if statement? It should be better avoid the locking.
NetBeans's automatic hint system obviously isn't aware that it's possible to do double-checked locking correctly with volatile, as you've done, so it suggests full locking instead. Better safe than sorry. But you're right in this case, not NetBeans.
Most of the time, the singleton will be used, and doesn't cost much to create, so just make it simple:
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
...
}
If you really want lazy instantiation, use a static inner class:
public class Singleton {
public static Singleton getInstance() {
return Holder.INSTANCE;
}
...
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
}
Don't listen to NetBeans in this situation. Your first code sample is correct.
In the code snippet below when I originally designed it, the "next number" needed to send the next incremented value throughout the execution of the application. So I made the class a singleton. However, with some recent change in requirements I needed to do a reset on the "next number". I just added a reset method to do that. However, it definitely violates the Singleton pattern and also I know it is not a good idea to initialize a static member this way.
What do you think I should do instead?
public final class GetNextNumber {
private static GetNextNumber instance;
private static Integer nextNumber=1;
private GetNextNumber() {
}
public static synchronized GetNextNumber getInstance() {
if(instance==null){
instance = new GetNextNumber();
}
return instance;
}
protected Integer getNextNumber(){
return nextNumber++;
}
protected synchronized void reset(){
nextNumber=1;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
why aren't the fields just instance variables? theres no need for static here.
reset doesn't need to be synchronized either, unless getNextNumber is as well.
Looks OK to me - except for two things:
getNextNumber is not synchronized.
since getNextNumber and reset are not static, nextNumber doesn't need to be static, either.
You could use an AtomicInteger to avoid having to make your getNextNumber and reset methods synchronized:
public final class GetNextNumber {
private static GetNextNumber instance;
private AtomicInteger nextNumber = new AtomicInteger(1);
private GetNextNumber() {
}
public static synchronized GetNextNumber getInstance() {
if(instance==null){
instance = new GetNextNumber();
}
return instance;
}
protected Integer getNextNumber(){
return nextNumber.getAndIncrement();
}
protected void reset(){
nextNumber.set(1);
}
}
For futher discussion on this, see for example The Atomic classes in Java 5: AtomicInteger and AtomicLong:
Before Java 5, we had to write classes
with access to the counter variable in
synchronized blocks or methods, or
else use a volatile variable which is
a lighter form of synchronization but
with the risk that some updates could
be missed if they happen concurrently.
An AtomicInteger can be used as a
drop-in replacement that provides the
best of both worlds...