I'm trying to convert some part of my project from java to kotlin. One of it is a singleton manager class. The java class looks like this
public class Manager {
private static volatile Manager Instance = null;
private static final Object InstanceLock = new Object();
private Manager(Object1 object1, Object2 object2, Object3 object3){//...};
public static boolean isInitialized(){
synchronized(InstanceLock){
return Instance == null;
}
}
public static void initialize(Object1 object1, Object2 object2, Object3 object3){
if(Instance == null){
synchronized(InstanceLock){
if(Instance == null){Instance = new Manager(object1, object2, object3};
}
}
}
public static getInstance(){
Precondition.checkNotNull(Instance, msg...);
return Instance;
}
}
Also, I decompiled .kt back to java. In the companion class I get the following code.
public static final class Companion {
#Nullable
public final Manager getInstance() {
return Manager.instance;
}
private final void setInstance(Manager var1) {
Manager.instance = var1;
}
private final Object getInstanceLock() {
return Manager.InstanceLock;
}
public final boolean isInitialized() {
Object var1 = Manager.Companion.getInstanceLock();
synchronized(var1){}
boolean var4;
try {
var4 = Manager.Companion.getInstance() == null;
} finally {
;
}
return var4;
}
public final void initialize(#NotNull String string1, #NotNull String string2) {
Intrinsics.checkParameterIsNotNull(string1, "string1");
Intrinsics.checkParameterIsNotNull(string2, "string2");
if (((Manager.Companion)this).getInstance() == null) {
Object var3 = ((Manager.Companion)this).getInstanceLock();
synchronized(var3){}
try {
if (Manager.Companion.getInstance() == null) {
Manager.Companion.setInstance(new Manager(string1, string2, (DefaultConstructorMarker)null));
}
Unit var5 = Unit.INSTANCE;
} finally {
;
}
}
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
1) How do I achieve thread safety, singleton by using lateinit or lazy inside the kotlin companion object ? As I can see, the decompiled java code has a synchronized call in initialize function but nothing in the synchronize body.
2) I think kotlin object/lazy comes with thread safety guarantee, how do I take advantage of it in the double-checked locking pattern ?
3) Is there a better pattern than double-checked locking pattern? Assuming the constructor does need arguments.
4) Since I'm trying to make the impact of converting this manager class to kotlin file as small as possible (this Manager file is supposed to work with the rest of java code), what is the best approach ? I do notice I have to add #Jvmstatic or #Jvmfield in some other variables or functions inside of companion object so that I don't have to update other java file that has call to these static field in manager.
5) Additional question, what if this manager is now working in pure kotlin environment, what's the best practice of implementing a singleton class with multiple arguments ?
The first answer does not address the synchronization, which, btw, is still an under appreciated complexity. There are still a ton of people running around saying simply do double-checked locking. But there are some pretty compelling arguments that show that DCL does not always work.
Interestingly, though, I had this same issue recently and found this article. While I did not like this the first time I found it, I revisited it a few times and warmed up to it, in large part because:
the author went and got code from the Kotlin stdlib
the result is a parameterized mechanism that while kind of ugly affords reuse, which is pretty compelling
Notice that the major issues are all broached in this treatment:
synchronization
complex initialization
parameterized initialization (crucial in Android, where the Context god object is ineradicable)
resulting compiled code
In short I think this is pretty much the first and last word on this topic, amazingly, found on Medium.
I don't have answer to all of your questions, but there is a defined way to create a singleton class in Kotlin.
Instead of class prefix in front of the class name, use object.
For example,
object Manager {
// your implementation
}
This make this class singleton and you can directly use this from Java like Manager.getInstance() (I didn't remeber the exact syntax but this should work) . Kotlin creates it for you.
You can check this for more reference.
Hope it will help you a little.
Related
If a Java class has a field that is initialized lazily or on demand, how can we ensure that access to the lazy field is via it's initializing access method?
By way of context, we recently had a situation in which a developer added access to an object that was initialized lazily, but not via its initializing access method. This wasn't caught at compilation or in unit tests, but then caused runtime errors.
For example - in the following SSCCE, _lazyObject is initialized via the getLazyObject() method. However, if there are other methods (in the class, because it already has a private access modifier) that would want to use _lazyObject, we should access via the getLazyObject() method, as otherwise it may not have been initialized.
public class MyObject {
private transient volatile Object _lazyObject;
public Object getLazyObject() {
if (_lazyObject == null) {
synchronized (this) {
if (_lazyObject == null) {
_lazyObject = new Object();
}
}
}
return _lazyObject;
}
public void doSomething() {
Object a = _lazyObject; // may be null - will compile, but may cause runtime errors!
Object b = getLazyObject(); // subject to exceptions, will not be null - this is how it should be accessed.
// do something...
}
}
How can we ensure that the access of _lazyObject is via getLazyObject()?
Is this possible in the code within MyObject?
Alternatively, is it possible to ensure this via unit tests?
Ok, so I'm open to further suggestions, but this is the best solution that I have come up with so far.
We can 'protect' the lazy variable in an initializing object - I thought about writing this myself, but found that there are good implementations of this in Apache Commons Lang (LazyInitializer) and Google Guava (Supplier). (Credit to Kenston Choi's answer to this question.)
For example - to clarify, I've changed the lazy object class from Object to a placeholder T:
public class MyObject {
private transient Supplier<T> _lazyObject = Suppliers.memoize(new Supplier<T>() {
#Override
public T get() {
return ...; // make T
}
});
public T getLazyObject() {
return _lazyObject.get();
}
public void doSomething() {
Supplier<T> a = _lazyObject; // a is actually the Supplier
// ... but we can access either via the method
T b = getLazyObject();
// or the Supplier:
T c = _lazyObject.get();
// do something...
}
}
However, as per the comments above - one of my main use cases is serializing/de-serializing objects containing lazy fields across JVMs. In this case, after de-serialization, the Supplier will be null. As such, we need to initialize the Supplier after deserialization.
For example, using the most simple approach:
public class MyObject {
private transient Supplier<T> _lazyObject = makeSupplier();
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
_lazyObject = makeSupplier();
}
private Supplier<T> makeSupplier() {
return Suppliers.memoize(new Supplier<T>() {
#Override
public Tget() {
return ...; // make T
}
});
}
}
For business decision applications, I run into a lot of cases where I must cache an expensive value with lazy initialization. So I leveraged generics and a Supplier lambda to encapsulate a lazy initialization.
import java.util.function.Supplier;
public final class LazyProperty<T> {
private final Supplier<T> supplier;
private volatile T value;
private LazyProperty(Supplier<T> supplier) {
this.supplier = supplier;
}
public T get() {
if (value == null) {
synchronized(this) {
if (value == null) {
value = supplier.get();
}
}
}
return value;
}
public static <T> LazyProperty<T> forSupplier(Supplier<T> supplier) {
return new LazyProperty<T>(supplier);
}
}
But I'd like to be able to use this also in cases where I can't initialize a property until after the object is created, because the object can only calculate this property after it is created (usually needing context of itself or other objects). However, this often requires a reference to this in the supplier function.
public class MyClass {
private final LazyProperty<BigDecimal> expensiveVal =
LazyProperty.forSupplier(() -> calculateExpensiveVal(this));
public BigDecimal getExpensiveVal() {
return expensiveVal.get();
}
}
As long as I can guarantee the LazyProperty's get() function is only called after MyClass is constructed (via the getExpensiveVal() method), there shouldn't be any partial construction issues due to the this reference in the supplier, correct?
Based on the little code you showed you should not have any problems but I would probably write your class like this to be more explicit:
public class MyClass {
private final LazyProperty<BigDecimal> expensiveVal;
public MyClass() {
this.expensiveVal = LazyProperty.forSupplier(() -> calculateExpensiveVal(MyClass.this));
}
public BigDecimal getExpensiveVal() {
return expensiveVal.get();
}
}
Your code will have one Problem which depends on the implementation of method calculateExpensiveVal.
if calculateExpensiveVal calls getExpensiveVal on the passed reference of MyClass you will get NullPointerException.
if calculateExpensiveVal creates a thread and pass the reference of MyClass, again you may run into the same problem as point 1.
But if you guarantee calculateExpensiveVal is not doing any of the things, then your code stand correct from Thread safety Perspective. MyClass will never be seen partially constructed
because of the final gaurantees provided by the JMM
After saying that even though your *calculateExpensiveVal may employ any one or both those points you are only going to have problem in getExpensiveVal method with NullPointerException.
your lazyProperty.get method is already thread safe so there woun'd be any problem.
Because you will always see fully constructed Supplier object because of final keyword (only if you didn't escaped 'this' reference to another thread) and you already have used volatile for value field which takes care of seeing fully constructed value object.
Is there any way to make field static or transient using java reflection API.
EDIT: I have some Beans that are already being serialised using soap api and is being used by some clients, for some clients i don't want to expose one or two fields.
Sure there are so many ways to do it without changing or adding transient keyword.
Just want to know if it can be done, and if so, how ?
EDIT: I wouldn't call it an API or framework issue, more like a design flaw...
I'm using apache axis2 for soap
No. Such a thing would require modifying the byte code of the class. A particular difficulty in the case of static fields is that they are accessed using different bytecodes than object fields.
I don't see a why a field couldn't be made transient in runtime, at least in theory, but the current reflection API doesn't allow it. See also: Can a field's transient property/flag be set through reflection in java?
You can't do it with the reflection api. I think there are some byte-code manipulation tools but in this case you can use the Decorator pattern. It solves the problem but I think it is extremely ugly:
(I omited the usual boilerplate from here such as interfaces)
public class StaticDecorator {
private static Object staticField;
private Object yourObject;
public StaticDecorator(Object yourObject) {
this.yourObject = yourObject;
}
public static Object getStaticField() {
return staticField;
}
public static void setStaticField(Object object) {
staticField = object;
}
}
I used Object for the type of the class you are going to wrap but of course you can substitute any type you want. Using an approach like this you can "decorate" any class with a static field.
If you are really, extremely must want a static field in an object at run time this can help you but I think that there is a design flaw lurking somewhere.
You can wrap your bean inside another bean that only exposes the fields that you'd like to expose through your API. For example, with an internal bean with the fields foo, bar, and baz, where you do not want to expose baz.
Lombok Delegation can make this incredibly simple, but here's an example using plain-old-Java.
public class ExposedBean {
private InternalBean internalBean;
public ExposedBean(InternalBean internalBean) {
this.internalBean = internalBean;
}
public String getFoo() { return internalBean.getFoo(); }
public String getBar() { return internalBean.getBar(); }
}
public class InternalBean {
private String foo;
private String bar;
private String baz;
public String getFoo() { return foo; }
public String getBar() { return bar; }
public String getBaz() { return baz; }
}
Original answer, regarding setting modifiers
You can not set modifiers. You can check them, however.
Field myField = /* get a field object */;
if (Modifier.isTransient(myField.getModifiers()) {
System.out.println("myField is transient.");
}
if (Modifier.isFinal(MyClass.class.getModifiers()) {
System.out.println("MyClass is final.");
}
With more information about the problem you're trying to solve, we can suggest alternatives. Member#getModifiers() is not declared final, so you could possibly use a decorator. (The below code is 100% untested.)
public class FieldModifierDecorator extends Field {
protected Field field;
private int modifiers = -1;
public static void decorate(Field field) {
FieldModifierDecorator newInstance = new FieldModifierDecorator();
newInstance.field = field;
return newInstance;
}
public void overrideModifiers(int modifiers) {
this.modifiers = modifiers;
}
public int getModifiers() {
if (-1 == modifiers) {
return field.getModifiers();
}
return modifiers;
}
}
// Example usage
public Field makeFieldAppearTransient(Field field) {
FieldModifierDecorator decoratedField = FieldModifierDecorator.decorate(field);
decoratedField.overrideModifiers(field.getModifiers() | Modifier.TRANSIENT);
// if (Modifier.isTransient(decoratedField.getModifiers())) {
// System.out.println("It looks transient, but really isn't.");
//}
return decoratedField;
}
Modfifying class information or byte code modification is definitely the wrong tool for the job. You are trying to solve a business problem with solely technical tools.
It sounds more like you need a permission concept. Users may have permission to see some fields. Based on that you could use java bean introspection to clear the values of those fields just before they are sent to the client.
However this might have its problems as well. A client should be able to determine if it has permission to see that field or not.
Good morning.
I am currently working on a Java Web Service project, that is deployed on an Apache Tomcat 7 server. For the needs of the project, I need to maintain a global (among WS threads, created by every request) object in memory. Thus, I tried to implement a Singleton design pattern as follows:
public class SingletonDesign {
private static boolean _instanceFlag = false;
private static final SingletonDesign _instance = new SingletonDesign();
private static GlobalObject _myGlobalObject;
private SingletonDesign() {
if(_instanceFlag == false) {
_myGlobalObject = new GlobalObject();
_instanceFlag = true;
}
}
public static GlobalObject getModel() {
if(_instanceFlag == false) {
_myGlobalObject = new GlobalObject();
_instanceFlag = true;
}
return _myGlobalObject;
}
public static int parseModel() {
if(_instanceFlag == false) {
_myGlobalObject = new ItemSimilarityModel();
_instanceFlag = true;
}
int val = _myGlobalObject.parseFromFile();
return val;
}
}
I am aware of the fact that every time a request is done, a new thread would be created on my Web – service class (object). My goal, is to have a global SingletonDesign object among all threads, which stays alive in memory, and is created only once.
Despite the fact that the above design seems to be working according to my expectations, I am not really sure if it is correct. So these are my questions:
1) Why do the methods of the SingletonDesign object need to be static? (I have attempted to define them as non-static, but my Singleton object is not initialized properly).
2) The above design is seen from the Wikipedia page on the Singleton Design Pattern. The part that confuses me is the initialization of the _instance field, which I have seen in other Singleton implementations too. Why do we need that object?
3) Does my object stay alive until the server stops? I have made some tests and It seems that it stays alive, but I have to be 100% sure.
Thank you for your time and interest.
The _instance field contains your singleton. You need a static getInstance() method, and your other methods would be instance methods. I don;t think you need the _instanceFlag field at all.
Then you would call it as follows:
SingletonDesign.getInstance().getGlobalObject();
Still, keep in mind that a lot of people (including myself) thing of Singleton as a code-smell. Also, this design is not considered the best way to implement a Singleton in Java, cfr: What is an efficient way to implement a singleton pattern in Java?
The object will stay alive as long as its classloader stays alive.
1) The only static method you actually need in a singleton is the method that returns the instance of the singleton. The method has to be static as you can't instantiate a singleton, and thus the method has to belong to the class instead of the object.
2) A simplified version that might be more easy to begin with:
public class MySingleton {
private static MySingleton instance = null;
private static String aString = null;
private MySingleton( {
aString = new String("Hello, world");
}
public static MySingleton getInstance() {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
public string getMyString() {
return aString;
}
}
3) To my knowledge is stays alive as long as the JVM runs.
As a tip, if you perform some sort of initialization code in the method returning the instance, I'd suggest also declaring the method as synchronized.
the lazy thread-safe singleton instantion is kinda not easy to understand to every coder, so i wanted to create a class in our enterprise framework that would do the job.
What do you think about it? Do you see something bad about it? Is there something similar like in Apache Commons? How can i make it better?
Supplier.java
public interface Supplier<T> {
public T get();
}
LazyThreadSafeInstantiator.java
public class LazyThreadSafeInstantiator<T> implements Supplier<T> {
private final Supplier<T> instanceSupplier;
private volatile T obj;
public LazyThreadSafeInstantiator(Supplier<T> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
#Override
// http://en.wikipedia.org/wiki/Double-checked_locking
public T get() {
T result = obj; // Wikipedia: Note the usage of the local variable result which seems unnecessary. For some versions of the Java VM, it will make the code 25% faster and for others, it won't hurt.
if (result == null) {
synchronized(this) {
result = obj;
if (result == null) {
result = instanceSupplier.get();
obj = result;
}
}
}
return result;
}
}
Example usage:
public class Singleton1 {
private static final Supplier<Singleton1> instanceHolder =
new LazyThreadSafeInstantiator<Singleton1>(new Supplier<Singleton1>() {
#Override
public Singleton1 get() {
return new Singleton1();
}
});
public Singleton1 instance() {
return instanceHolder.get();
}
private Singleton1() {
System.out.println("Singleton1 instantiated");
}
}
Thanks
the lazy thread-safe singleton
instantion is kinda not easy to
understand to every coder
No, it's actually very, very easy:
public class Singleton{
private final static Singleton instance = new Singleton();
private Singleton(){ ... }
public static Singleton getInstance(){ return instance; }
}
Better yet, make it an enum:
public enum Singleton{
INSTANCE;
private Singleton(){ ... }
}
It's threadsafe, and it's lazy (initialization happens at class loading time, and Java does not load classes until they are are first referred).
Fact is, 99% of the time you don't need lazy loading at all. And out of the remaining 1%, in 0.9% the above is perfectly lazy enough.
Have you run a profiler and determined that your app belings to the 0.01% that really needs lazy-loading-at-first-access? Didn't think so. Then why are you wasting your time concocting these Rube Goldbergesque code abominations to solve a non-existing problem?
For a version that is more readable (in my opinion) than the one presented in the question, one can refer to the Initialization on Demand Holder idiom, introduced by Bill Pugh. Not only is it thread-safe considering the Java 5 memory model, the singleton is also lazily initialized.
Looks overengineered to me.
I really don't see how having helper class helps.
First of all, it's using double-locking idiom, and it has been proved once and again broken.
Second, if you HAVE TO use singleton, why not initialize static final instance.
public class Singleton1 {
private static final Singleton1 instanceHolder =
new Singletong1( );
public Singleton1 instance() {
return instanceHolder;
}
private Singleton1() {
System.out.println("Singleton1 instantiated");
}
}
This code is thread-safe and has been proven to work.
Check Vineet Reynolds' answer for when you need to initialize singleton instance on a first get. In many cases I think that approach is an overkill as well.
Isn't the double checked locking pattern and use of volatile broken on JIT compilers and multi-core/processor systems due to the Java Memory Model & possibility of out of order execution?
More generally, it seems that a framework for singletons is overkill for what is essentially a pretty straightforward pattern to implement correctly.
I would agree with other posters and say that this does seem like overkill, but have said that i do think that this is something that a junior developer is likely to get wrong. I think that because the behaviour of the supplier that constructs the singleton (shown below) is going to be the same in nearly all cases, i would be tempted to put this as default behaviour in the LazyThreadSafeInstantiator. The use of the annonomous inner class every time you want to use a singleton is really messy.
#Override
public Singleton1 get() {
return new Singleton1();
}
This could be done by providing an overloaded constructor that takes the Class to the singleton required.
public class LazyThreadSafeInstantiator<T> implements Supplier<T> {
private final Supplier<T> instanceSupplier;
private Class<T> toConstruct;
private volatile T obj;
public LazyThreadSafeInstantiator(Supplier<T> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
public LazyThreadSafeInstantiator(Class<t> toConstruct) {
this.toConstruct = toConstruct;
}
#Override
// http://en.wikipedia.org/wiki/Double-checked_locking
public T get() {
T result = obj; // Wikipedia: Note the usage of the local variable result which seems unnecessary. For some versions of the Java VM, it will make the code 25% faster and for others, it won't hurt.
if (result == null) {
synchronized(this) {
result = obj;
if (result == null) {
if (instanceSupplier == null) {
try {
Constructor[] c = toConstruct.getDeclaredConstructors();
c[0].setAccessible(true);
result = c[0].newInstance(new Object[] {});
} catch (Exception e) {
//handle
}
result =
} else {
result = instanceSupplier.get();
}
obj = result;
}
}
}
return result;
}
}
This would then be used like so.
private static final Supplier<Singleton1> instanceHolder =
new LazyThreadSafeInstantiator<Singleton1>(Singleton1.getClass());
This is my opinion is a bit cleaner. You could alos extend this further to use constructor arguments.
Lazy<X> lazyX= new Lazy<X>(){
protected X create(){
return new X();
}};
X x = lazyX.get();
abstract public class Lazy<T>
{
abstract protected T create();
static class FinalRef<S>
{
final S value;
FinalRef(S value){ this.value =value; }
}
FinalRef<T> ref = null;
public T get()
{
FinalRef<T> result = ref;
if(result==null)
{
synchronized(this)
{
if(ref==null)
ref = new FinalRef<T>( create() );
result = ref;
}
}
return result.value;
}
}
except maybe the first get() in a thread, all get() calls require no synchronization or volatile read. the original goal of double checked locking is achieved.