I am having a difficult time understanding the way static classes are using in the following scenario.
Let’s say I declare a class as follows:
public class TestLibrary {
private static final TestLibrary library = new TestLibrary();
private ErrorHandler errorHandler = null;
public static TestLibrary getLibrary() {
return library;
}
public ErrorHandler getErrorHandler() {
return errorHandler;
}
public int run(String[] args) {
this.initialize(args);
}
private void initialize(String[] data) {
library.errorHandler = new ErrorHandler();
}
}
I now change the class slightly to
private void initialize(String[] data) {
errorHandler = new ErrorHandler();
}
I declare errorHandler in other classes as follows:
private ErrorHandler errorHandler = TestLibrary.getLibrary().getErrorHandler();
My code ultimately still functions the same when I use the instance of errorHandler in other classes, but I don’t understand why.
Question 1: Shouldn’t the 2nd case create a new ErrorHandler that is part of the object TestLibrary.errorHandler rather than library.errorHandler?
Question 2: Am I doing something wrong? Could you elaborate?
What you have there is a static method getLibrary() that returns the same instance for all callers. That's called a Singleton - although there's better ways to code them.
Then again your supposed Singleton (TestLibrary) exhibits methods that when called change internal state - most important, the ErrorHandler.
This will cause strange behaviour, especially in multithreaded systems.
Code like this:
TestLibrary.getLibrary().run("".split(""));
ErrorHandler eh = TestLibrary.getErrorHandler();
assertEquals(eh, TestLibrary.getErrorHandler());
might fail. Because someone (meaning: some other thread) might have just happend to call init() between lines 2 and 3, causing ErrorHandler to be set to just another value.
If you need to initialize your TestLibrary before use, you should do it once, and once only - so you're better of putting this into the constructor of TestLibrary.
If you need TestLibraries that are intialized different throughout your code, you should remove the Singleton pattern and stick to plain
TestLibrary tl = new TestLibrary();
tl.run("".split(""));
Read more about Singleton in What is an efficient way to implement a singleton pattern in Java?
Related
I am designing a game in libgdx, and i decided to make certain manager classes singletons because I noticed that I was often only using one instance of a class, and then passing the same instance to many other classes through constructors, which was very painful to do. Now, I have one manager class that initializes many other classes in it's constructor. I did this by using static block initializers for each class, like so:
public class Example{
private static Example instance;
static{
try{
synchronized(Example.class){
instance = new Example();
}
}catch(Exception e){
throw new RunTimeException("Failure to initialize Example instance");
}
public static Example getInstance(){
return instance;
}
In the main manager I create an instance of each class through the getInstance method.
The problem that arises is this: say I have static singleton classes Example1 and Example2.
In Example1's constructor I make a variable called:
example2 = Example2.getInstance();
but because example2 and example1 need to use each other's methods, in Example2's constructor I make:
example1 = Example1.getInstance();
The problem should be easy to see. Because example1 is waiting for example2 to finish initializing, and example2 needs example1's instance, it ends up creating a deadlock and crashing through the above codes RunTimeException.
this seems easy to fix using just two example classes, but the problem is confounded when I have 6 different singleton manager classes that almost all need to communicate in some way. Easiest solution would obviously not use this methodology, but that would require me to rewrite most of my code.
I can't figure out how to use this methodology of singleton classes without running into this issue, as most of the classes need information from the other classes in the constructor in order to function.
do I remove all of the code from the constructors of the singleton classes, or do something else?
It's not a deadlock, it's infinite recursion. There is no way around it, you must refactor your code.
Best thing is not to have any logic in your constructors, just initialization of member variables. Since you don't need to store the singletons as members in your classes, there really should be no need to access them in your constructors. Just use the appropriate getInstance() method to access a singleton from inside the methods of your other singletons.
I don't use many singletons any more. I consider a singleton to be a use case, rather than a "type of class", and then rely on something else to manage the "singleton-ness" of it (such as an injection framework). When I don't have one of those, I create a single "singleton" to manage the applications classes-to-be-used-as-singletons.
So, in this case, you can have this class manage the construction and interdependencies for you rather than have the classes manage them for themselves.
public class Singletons {
private Example1 example1;
private Example2 example2;
private Example3 example3;
private static Singletons instance;
static {
Example1 example1 = new Example1();
Example2 example2 = new Example2();
Example3 example3 = new Example3();
instance = new Singletons();
example1 = new Example1();
example2 = new Example2();
example3 = new Example3();
example1.setExample2(example2);
example2.setExample3(example3);
example3.setExample1(example1);
instance.setExample1(example1);
instance.setExample2(example2);
instance.setExample3(example3);
}
public Example1 getExample1() {
return example1;
}
private void setExample1(Example1 example1) {
this.example1 = example1;
}
public Example2 getExample2() {
return example2;
}
private void setExample2(Example2 example2) {
this.example2 = example2;
}
public Example3 getExample3() {
return example3;
}
private void setExample3(Example3 example3) {
this.example3 = example3;
}
public Singletons getInstance() {
return instance;
}
}
I have a library that I am required to use that has a dangerous initialization of a static value (the classes have been stripped down to the minimum for the example):
public TheirBaseClass {
public static String PathToUse = null;
public BaseClass(){
PathToUse = "Configured";
// ...
// do some other stuff with other side effects
// ...
}
}
I have a case where I attempt to read from the value ConfigValue without instantiating the class (to avoid some of the sideeffects).
Paths.get(TheirBaseClass.PathToUse).toFile()....
This causes a NullPointerException
Because I am required to use this class, I am looking to inherit from it, and attempt to take action to ensure that initialization has taken place when accessing the static.
public MyBaseClass extends TheirBaseClass{
private static final AtomicBoolean isInitialized = new AtomicBoolean(false);
static {
MyBaseClass.Initialize();
}
public static void Initialize(){
// FindBugs does not like me synchronizing on a concurrent object
synchronized(isInitialized){
if( isInitialized.get() ){
return;
}
new TheirBaseClass();
isInitialized.set(true);
}
}
public MyBaseClass(){
super();
}
}
Which allows me to
MyBaseClass.Initialize();
Paths.get(MyBaseClass.PathToUse).toFile()....
This seems to be working reasonably well (and resolves some other phantom defects we've been having). It allows TheirBaseClass to function naturally, while allowing me to safely force initialization in the couple of cases I may need to.
However when I run FindBugs against this code, I get JLM_JSR166_UTILCONCURRENT_MONITORENTER. After reading the description, I agree that the use of AtomicBoolean could be dangerous because someone else could change the value, but...
I think its safe to ignore in this case (but have a doubt)
I generally prefer to rewrite code than put an ignore marker in place
Am I actually doing something dangerous (and just don't see it)? Is there a better way to do this?
Unfortunately, using a different TheirBaseClass is not an option.
Related
Are Java static initializers thread safe?
You might find it easier to adapt the lazy holder idiom:
public MyBaseClass {
private static class Initializer {
static {
new TheirBaseClass();
}
// Doesn't actually do anything; merely provides an expression
// to cause the Initializer class to be loaded.
private static void ensureInitialized() {}
}
{
Initializer.ensureInitialized();
}
// Rest of the class.
}
This uses the fact that class loading happens only once and is synchronized (within a single class loader). It happens only when you instantiate a MyBaseClass.
I want to store an object state between activities (already considered Parcelables, JSON, yadda yadda) but since I have a couple of Singletons, might as well refer to them in a class that extend Application (modularity + easy to maintain).
So to my question, let's say I have a simple singleton:
class SimpleSingleton
{
private static final SimpleSingleton instance; //The question will refer this line later.
public static SimpleSingleton getInstance()
{
return instance;
}
private SimpleSingleton(){}
}
1: At first I create an initInstance() method within the above class, e.g:
class SimpleSingleton
{
//... the code above
public static void initInstance()
{
if(instance == null) instance = new SimpleSingleton();
}
}
2: Hence the below works, (in which afterwards, I can refer to the singleton from any activity via CustomSingleton.getInstance()):
class MyApp extends Application
{
#Override
public void onCreate()
{
super.onCreate();
initSingletons();
}
protected void initSingletons()
{
SimpleSingleton.initInstance();
}
}
BUT. What if I declare
private static final SimpleSingleton instance = new SimpleSingleton();
instead of
private static final SimpleSingleton instance;
in the SimpleSingleton class?
I assume the object is initialized during compile time, so doesn't that makes the whole #1 and #2 unnecessary? Or do I get the order wrong (especially WHEN the class is actually initialized)? I came from C# and currently developing for Android so this kinda gave me a quick gotcha when I want to refer to my Singletons. Also, I ask this since according to this blog:
The explanation of the weird behavior I saw that makes more sense to me is that the static variables instances are bound to the class loader of the class that first initialized them.
The only difference i can think of is when you do
private static final CustomObject instance = new CustomObject();
when you application is launched it will create and allocate space for it.
Note it might never be used but it would still be using memory.
when you create it on an onCreate method it will only create an instance when it is called.
Using static also has one more disadvantage that is it will use your perm gen space and if by chance it fails to give it space or fails to create it your program will crash on startup. Leaving you confused.
I strongly suggest using the onCreate method approach.
I know Java basics, and now I'm in the journey of reading Effective Java. The book suggest using static factory methods instead of constructors. So I have Groovy code like this:
public class Anto {
public static void main(String[] args) {
println Java.javaInstance()
}
}
class Java {
public static Java javaInstance() {
return this
}
}
When I compile this, I get an error like this:
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
at Java.javaInstance(Anto.groovy:9)
at Java$javaInstance.call(Unknown Source)
at Anto.main(Anto.groovy:3)
Where am I making a mistake?
You can do it using return new Java();. Static methods don't have access to this.
EDIT:
These static factories are usually singletons, which means that only one instance of the class should be used (typically, a connection to a db for example). If you want do add this dimension to your Java class, use a private static attribute as follow:
class Java {
private static Java instance;
public static Java javaInstance() {
if(instance == null) {
instance = new Java();
}
return instance;
}
}
Creating a Singleton correctly can be easy to get wrong (especially in a multi-threaded environment), so you're probably better using the Singleton annotation that comes with Groovy rather than rolling your own:
public class Anto {
public static void main(String[] args) {
println Java.instance
}
}
#Singleton
class Java {
}
This transforms the Java class to:
class Java {
private static volatile Java instance
private Java() {}
static Java getInstance () {
if( instance ) {
instance
} else {
synchronized( Java ) {
if( instance ) {
instance
} else {
instance = new Java()
}
}
}
}
}
A good (albeit not specific to Groovy) example of a library that uses static factory methods that you could look at would be Google Guava. Guava uses this idiom in a number of places. For example, their Range class supports nine types of ranges, and if they used normal constructors, their signatures would conflict in several cases since the only thing you can use to distinguish them is their arguments.
Static methods on the other hand can also be distinguished by their name, so Guava defines different ones for each type of Range. Internally these methods still call a normal constructor, but it's not one that's publicly accessible.
import com.google.common.collect.Ranges
import com.google.common.collect.DiscreteDomains
final dom = DiscreteDomains.integers()
assert [1,2,3,4,5] as Set == Ranges.closed(1, 5).asSet(dom)
assert [2,3,4] as Set == Ranges.open(1, 5).asSet(dom)
This is a useful idiom, but not one that should just be automatically preferred over a normal constructor. In situations where a normal constructor would have sufficed, you've at best written more code than you needed and at worst have made extending the class impossible, since any subclasses will still need a public or protected constructor they can call.
You can't use this because static methods are not instance methods.
Each time you create a new instance of a particular class, that new object/instance as it's own state. this points to a particular instance.
Are you trying to make a singleton ? Meaning you just want a single instance of a class ?
class Singleton {
//static reference to a particular instance
private static Singleton instance;
//private constructor so that it cant be called outside this class scope
private Singleton();
//synchronized in case your working in threaded enviroment
public synchronized static Singleton getInstance()
{
if(NULL == instance)
{
instance = new Singleton();
}
return instance;
}
}
I have a class that might throw any run-time exceptions during initialization. I want the class to be a singleton since the cost of keeping several objects in memory is high. I am using that class in another class.
My use case is as follows:
I have to use a single instance of Controller.
Each instance of Parent must use the same Controller instance.
Controller
constructor might throw exceptions.
If instantiation fails, I should
retry to instantiate after sometime.
So I check if my Controller instance is null when I try to do a "get" on the Controller, if yes, I try to instantiate it again.
Following is my code:
class Parent
{
private static volatile Controller controller;
private static final Object lock = new Object();
static
{
try
{
controller = new Controller();
}
catch(Exception ex)
{
controller = null;
}
}
private Controller getController() throws ControllerInstantiationException
{
if(controller == null)
{
synchronized(lock)
{
if(controller == null)
{
try
{
controller = new Controller();
}
catch(Exception ex)
{
controller = null;
throw new ControllerInstatntationException(ex);
}
}
}
}
return controller;
}
//other methods that uses getController()
}
My question is, is this code broken? I read somewhere that the above code would be a problem in JVM 1.4 or earlier. Can you provide references/solutions? Please note that I am asking this question because there is a lot of confusion regarding this topic in the internet.
Thanks.
I believe it's not broken, cause of volatile declaration. But imho better to avoid code like this. There is no guarantee, that this code will work with Java 8 for example. There are another way to create lazy singleton. I always (almost) use this method. First time faced with it in Java Concurrency in Practice book.
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
I don't know what you are doing in your code, it's hard to say, how to tweak it. The most straightforward way, simply use synchronize method. Do you seriously want to receive some performance benefit using double-check-locking ? Is there bottle-neck in synch method ?
The only thing which is broken is to make the example far more complicated than it needs to be.
All you need is an enum
// a simple lazy loaded, thread safe singleton.
enum Controller {
INSTANCE
}
Using an AtomicBoolean (much like I suggested here) would be safer and allows for repeat attempts at instantiation on failure.
public static class ControllerFactory {
// AtomicBolean defaults to the value false.
private static final AtomicBoolean creatingController = new AtomicBoolean();
private static volatile Controller controller = null;
// NB: This can return null if the Controller fails to instantiate or is in the process of instantiation by another thread.
public static Controller getController() throws ControllerInstantiationException {
if (controller == null) {
// Stop another thread creating it while I do.
if (creatingController.compareAndSet(false, true)) {
try {
// Can fail.
controller = new Controller();
} catch (Exception ex) {
// Failed init. Leave it at null so we try again next time.
controller = null;
throw new ControllerInstantiationException(ex);
} finally {
// Not initialising any more.
creatingController.set(false);
}
} else {
// Already in progress.
throw new ControllerInstantiationException("Controller creation in progress by another thread.");
}
}
return controller;
}
public static class ControllerInstantiationException extends Exception {
final Exception cause;
public ControllerInstantiationException(Exception cause) {
this.cause = cause;
}
public ControllerInstantiationException(String cause) {
this.cause = new Exception(cause);
}
}
public static class Controller {
private Controller() {
}
}
}
Yes, it is guaranteed to work by the Java Memory Model on modern JVMs. See the section Under the new Java Memory Model in The "Double-Checked Locking is Broken" Declaration.
As other answers have pointed out, there are simpler singleton patterns, using Holder classes or enums. However, in cases like yours, where you want to allow for trying to reinitialize several times if the first try fails, I believe that double-checked locking with a volatile instance variable is fine.
It is not an answer to your question but this famous article on Double-Checked Locking is Broken explains well as to why it is broken for java 1.4 or earlier version.