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...
Related
I'm studying basic software design pattern.
The basic implementation of singleton classes are written like this:
public class MyObject{
private volatile static MyObject obj;
private MyObject(){/*Do some heavy stuff here*/}
public static synchronized MyObject getInstance(){
if(obj==null)
obj=new MyObject();
return obj;
}
}
But as I have undestood calling synchronized methods can be heavy.
I while back I red a book the introduced this kind of implementation of Singleton class:
public class MyObjectHolder {
private volatile static Supplier<MyObject> myObjectSupplier = () -> createMyObj();
//myObjectSupplier is changed on the first 'get()' call
public static MyObject getMyObject(){
return myObjectSupplier.get();
}
private static synchronized MyObject createMyObj(){
class MyObjectFactory implements Supplier<MyObject> {
private final MyObject clockTimer = new MyObject();
public MyObject get() { return clockTimer; }
}
if(!MyObjectFactory.class.isInstance(myObjectSupplier)) {
myObjectSupplier = new MyObjectFactory();
}
return myObjectSupplier.get();
}
public static class MyObject{
private MyObject(){
/*Do some heavy stuff here*/
}
public void someMethod(){
/* ... */
}
}
}
...
{
/*In main MyObject instantiation*/
MyObjectHolder.MyObject obj = MyObjectHolder.getMyObject();
}
Now after the first call for 'createMyObj()' has been has been finished, there is no heavy burden of synchronized method calling and the is no if check neither.
Do you think there is something wrong with this kind of implementation?
ps. MyObject does not have to be an inner class of MyObjectHold but I thought it looked nice.
[UPDATED] Another solution that is called Initialization on Demand Holder idiom :
public class SingletonObject {
private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
private static final AtomicInteger INVOKE_COUNT = new AtomicInteger();
private static final class LazyHolder {
private static final SingletonObject INSTANCE = new SingletonObject();
}
private SingletonObject() {
System.out.println("new SingletonObject");
INSTANCE_COUNT.getAndIncrement();
}
public static SingletonObject getInstance() {
INVOKE_COUNT.getAndIncrement();
return LazyHolder.INSTANCE;
}
public static int getInstanceCount() {
return INSTANCE_COUNT.get();
}
public static int getInvokeCount() {
return INVOKE_COUNT.get();
}
}
to prove that it's thread-safe :
public static void main(String[] args) throws Exception {
int n = 1000;
List<Callable<SingletonObject>> invokers = new ArrayList<>();
for (int i = 0; i < n; i++) {
invokers.add(SingletonObject::getInstance);
}
ExecutorService es = Executors.newFixedThreadPool(n);
es.invokeAll(invokers);
es.shutdown();
System.out.println("Number of Instances = " + SingletonObject.getInstanceCount());
System.out.println("Number of Invokes = " + SingletonObject.getInvokeCount());
}
Output :
new SingletonObject
Number of Instances = 1
Number of Invokes = 1000
EDIT (after #Holger's comment) :
the use of the Nested Holder Class is somewhat necessary to Lazily Initialize the SingletonObject.
public class SingletonObject {
private static final SingletonObject INSTANCE = new SingletonObject();
private SingletonObject() {
System.out.println("new SingletonObject");
}
public static SingletonObject getInstance() {
return INSTANCE;
}
public static void anotherStaticMethod() {
System.out.println("I don't need the SingletonObject Instance...");
}
}
So what happens if someone invokes the anotherStaticMethod()?
new SingletonObject
I don't need the SingletonObject Instance...
UPDATE :
The page at WIKIPEDIA says :
The implementation of the idiom relies on the initialization phase of execution within the Java Virtual Machine (JVM) as specified by the Java Language Specification (JLS). When the class SingletonObject is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class SingletonObject, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class SingletonObject. Since the class initialization phase is guaranteed by the JLS to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. And since the initialization phase writes the static variable INSTANCE in a serial operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead.
This gives a highly efficient thread-safe "singleton" cache, without synchronization overhead; benchmarking indicates it to be far faster than even uncontended synchronization. However, the idiom is singleton-specific and not extensible to pluralities of objects (e.g. a map-based cache).
Also keep an eye on this.
The easiest way to implement the Singleton pattern in java is to simply make the class an enum instead:
public enum MyObject{
Obj;
MyObject(){/*Do some heavy stuff here*/}
}
Obj is guaranteed by the specification to only be created once on the first use of it.
Singleton pattern breaks Single Responsibility Principle (SRP) - because the class has to do two things:
It's primary task
Enforcing singleton-ness.
Your second approach is trying to delegate this 'Enforcing singleton-ness' to a separate class - following SRP. If you are using a dependency injection framework like spring, you can achieve the same effect by only defining MyObject class and declaring this class with a 'singleton' scope in the spring context.
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.
class Bob {
private static final Object locke = new Object();
private static volatile int value;
public static void fun(){
synchronized(locke){
value++;
}
}
}
How is this different from synchronizing on the class, i.e. synchronized(Bob.class){...}
Some other code can break yours by doing a synchronized(Bob.class). If they do, your code suddenly contests with their code for the lock, possibly breaking your code.
That danger is removed if the lock object is not accessible from outside the object that needs it.
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;
}
This is a question concerning what is the proper way to synchronize a shared object in java. One caveat is that the object that I want to share must be accessed from static methods. My question is, If I synchronize on a static field, does that lock the class the field belongs to similar to the way a synchronized static method would? Or, will this only lock the field itself?
In my specific example I am asking: Will calling PayloadService.getPayload() or PayloadService.setPayload() lock PayloadService.payload? Or will it lock the entire PayloadService class?
public class PayloadService extends Service {
private static PayloadDTO payload = new PayloadDTO();
public static void setPayload(PayloadDTO payload){
synchronized(PayloadService.payload){
PayloadService.payload = payload;
}
}
public static PayloadDTO getPayload() {
synchronized(PayloadService.payload){
return PayloadService.payload ;
}
}
...
Is this a correct/acceptable approach ?
In my example the PayloadService is a separate thread, updating the payload object at regular intervals - other threads need to call PayloadService.getPayload() at random intervals to get the latest data and I need to make sure that they don't lock the PayloadService from carrying out its timer task
Based on the responses, I refactored to the following:
public class PayloadHolder {
private static PayloadHolder holder;
private static PayloadDTO payload;
private PayloadHolder(){
}
public static synchronized PayloadHolder getInstance(){
if(holder == null){
holder = new PayloadHolder();
}
return holder;
}
public static synchronized void initPayload(){
PayloadHolder.payload = new PayloadDTO();
}
public static synchronized PayloadDTO getPayload() {
return payload;
}
public static synchronized void setPayload(PayloadDTO p) {
PayloadHolder.payload = p;
}
}
public class PayloadService extends Service {
private static PayloadHolder payloadHolder = PayloadHolder.getInstance();
public static void initPayload(){
PayloadHolder.initPayload();
}
public static void setPayload(PayloadDTO payload){
PayloadHolder.setPayload(payload);
}
public static PayloadDTO getPayload() {
return PayloadHolder.getPayload();
}
...
Is this approach legitimate? I am also curious if it is better to do it this way or using the AtomicReference approach mentioned by Hardcoded ...?
- I am keeping an instance of PayloadHolder on PayloadService simply to keep a reference to the PayloadHolder class active in the jvm for as long as the PayloadService is running.
Your code should look like this:
public static void setPayload(PayloadDTO payload){
synchronized(PayloadService.class){
PayloadService.payload = payload;
}
}
public static PayloadDTO getPayload() {
synchronized(PayloadService.class){
return PayloadService.payload ;
}
}
Your original code wouldn't have worked even if the methods weren't static. The reason being is you were synchronizing on the payload instance that you were changing.
Update, a response to johnrock comment:
Locking the whole class is only a problem if you have other synchronized static blocks that you want to run currently. If you want to have multiple independent locked section then I suggest you do something like this:
public static final Object myLock = new Object();
public static void setPayload(PayloadDTO payload){
synchronized(myLock){
PayloadService.payload = payload;
}
}
public static PayloadDTO getPayload() {
synchronized(myLock){
return PayloadService.payload ;
}
}
Or, if you require a more complex concurrency pattern look at java.util.concurrent which has many pre-built classes to aid you.
You could, as mentioned in other posts, synchronize on the class or on an explicit monitor.
There are 2 other ways, if we assume that your are using the sychnronize only for thread-safe getting and setting of the property: volatile and AtomicReference.
volatile
The volatile keyword will make access to the variable atomic, meaning that reading and assigning the variable won't be optimized by the CPUs local registers and are done atomically.
AtomicReference
The AtomicReference is a special class at the java.util.concurrent.atomic package, which allows atomic access to a variable-like reference. It is very similiar to volatile, but gives you some additional atomic operations, like compareAndSet.
Example:
public class PayloadService extends Service {
private static final AtomicReference<PayloadDTO> payload
= new AtomicReference<PayloadDTO>(new PayloadDTO());
public static void setPayload(PayloadDTO payload){
PayloadService.payload.set(payload);
}
public static PayloadDTO getPayload() {
return PayloadService.payload.get ;
}
Edit:
Your Holder seems quite confused, since you are instantiating classes only to call static Methods. A try to get it fixed with AtomicReference:
public class PayloadHolder {
private static AtomicReference<PayloadHolder> holder = new AtomicReference<PayloadHolder();
//This should be fetched through the holder instance, so no static
private AtomicReference<PayloadDTO> payload = new AtomicReference<PayloadDTO>();
private PayloadHolder(){
}
public static PayloadHolder getInstance(){
PayloadHolder instance = holder.get();
//Check if there's already an instance
if(instance == null){
//Try to set a new PayloadHolder - if no one set it already.
holder.compareAndSet(null, new PayloadHolder());
instance = holder.get();
}
return instance;
}
public void initPayload(){
payload.set(new PayloadDTO());
//Alternative to prevent a second init:
//payload.compareAndSet(null, new PayloadDTO());
}
public PayloadDTO getPayload() {
return payload.get;
}
public void setPayload(PayloadDTO p) {
payload.set(p);
}
}
public class PayloadService extends Service {
private final PayloadHolder payloadHolder = PayloadHolder.getInstance();
public void initPayload(){
payloadHolder.initPayload();
}
public void setPayload(PayloadDTO payload){
payloadHolder.setPayload(payload);
}
public PayloadDTO getPayload() {
return payloadHolder.getPayload();
}
}
My question is, If I synchronize on a static field, does that lock the class the field belongs to similar to the way a synchronized static method would? Or, will this only lock the field itself?
No, it just lock in the object itself ( the class attribute not the whole class )
Is this a correct/acceptable approach ?
You could probably take a look at the java.util.concurrent.lock package.
I don't really like synchronizing on a class attribute, but I guess that's just a matter of teste.
Synchronize on another static object that does not change:
public class PayloadService extends Service {
private static PayloadDTO payload = new PayloadDTO();
private static final Object lock = new Object();
public static void setPayload(PayloadDTO payload){
synchronized(lock){
PayloadService.payload = payload;
}
}
public static PayloadDTO getPayload() {
synchronized(lock){
return PayloadService.payload ;
}
}
Is this a correct/acceptable approach ?
No, the reason for this is that you should never synchronize on an variable/field that can change its value. That is, when you synchronize on PayloadService.payload and set a new PayloadService.payload, then you are violating a golden rule of synchronization.
You should either synchronize on the class instance or create some arbitrary private static final Object lock = new Object() and synchronize on that. You will have the same effect as synchronizing on the class.
There is a major part of functionality in this class which isn't posted which contributes to whether or not this approach is thread-safe: how do you access the PayloadDTO instance from the other parts of this class where it is used?
If you are providing methods which could swap in another instance for payload while another thread is running code which uses the payload object, then this is not thread safe.
For example if you have a method execute() which does the main work of this class and invokes methods on payload, you need to make sure that one thread cannot change the payload instance with the setter method while another thread is busy running execute().
In short, when you have shared state, you need to synchronize on all read and write operations on the state.
Personally I don't understand this approach and would never take it - providing static methods to allow other threads to re-configure a class smells like a violation of separation of concerns.