Synchronized methods in the generated factory.

3 views
Skip to first unread message

Vicio

unread,
Jan 5, 2009, 9:06:25 AM1/5/09
to Spring ME
The current implementation generates synchronized private getters in
the factory and the getInstance() method is synchronized as well.
But after the objects are created the synchronization could be avoid.

With the Java memory model of J2ME, the famous double checked locking
would not work. In fact only since Java 1.5 the system doesn't allow a
write of a volatile to be reordered with respect to any previous read
or write, and a read of a volatile cannot be reordered with respect to
any following read or write (at least if I really have understood
it :-).

Since the main instance field is static a simpler solution could be
the "Initialization on demand holder" idiom (http://en.wikipedia.org/
wiki/Initialization_on_demand_holder_idiom) :

public class ObnBeanFactory{
private ObnBeanFactory () {
}


private static class LazyHolder {
private static final ObnBeanFactory __INSTANCE= new
ObnBeanFactory ();
}


public static ObnBeanFactory getInstance() {
return LazyHolder.__INSTANCE;
}
}


Basically the inner class is only initialized when __INSTANCE is
accessed for the first time and then the private constructor is
called. Since the class initialization is guaranteed by the JLS to be
serial, no synchronization is required in the static getInstance().


Probably also for all the other private fields this could be applied
making them static and defining for each one a LazyHolderField class.
Things would be different since normally we want also to initialize
the objects... but maybe a solution could be to let the
LazyHolderField class extend the class field, define the
initialization in the constructor and use the LazyHolderField class
for the inner field.


Something like this:


//Not anymore synchronized and static...
final private static com.my-package.MyService getMyService() {
return LazyHolderMyService.__INSTANCE;
}


//Extending the original class...
private static class LazyHolderMyService extends MyService {
//Maintaining an object of the new class
private static final LazyHolderMyService __INSTANCE = new
LazyHolderMyService();


public LazyHolderMyService() {
setSomething(getSomething());
setSomethingElse(getSomethingElse());
... ...
}
}


Is this correct? Not sure if I'm missing something...
Of course this wouldn't be possible for final classes and in that case
the normal lazy loading with synchronized should be implemented...
hoping no one will call getBean() for that class in "hot" part of his/
her code in a multithread fashion.



Ciao,
Vicio.

wilfred

unread,
Jan 7, 2009, 1:11:13 AM1/7/09
to Spring ME
Did we run into any issues while not having this? I would expect that
the number of times you need access to an instance of the BeanFactory
are fairly limited. How big of a problem would the lock on BeanFactory
be? I like the approach, but it does introduce additional complexity
and additional class files. (Not necessarily desirable on Java ME.)

I have also been wondering if it wouldn't make sense to pull
management of the single instance out of the BeanFactory getting
generated. It is in a way a separate concern, and could be done easily
by something outside of this generated class. That way you could have
it your way as well. What do you think?
Reply all
Reply to author
Forward
0 new messages