This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
I am a relatively newbie to the Java world so please excuse my ignorance.
I am creating a library that returns one and only one object of a class. Before you say, you need to create a Singleton class, please hear me out.
Why I need a single object :- Because this class provides a service and this service needs to be initialized only once.
Problem :- This class would hold some critical resources. How should we release these resources.
IMHO a code like the following is not correct. Here I have deliberately not taken care of synchronization
This would obviously violate Singleton class principal so how should I actually design the Foo class.
If you tell the truth you don't have to remember anything.
-- Mark Twain
Aargh,, yes indeed the keyword static was missing. However, this is not the actual problem.
Assume that there are two different references to the Foo object.
Now calling foo.destroy() on one of the object would obviously change the state of Foo object and thus invalidating member resource. Now any operation on the second reference that uses "resource" member is also invalid.
So how should we safely release such resources in a manner so that the other objective, namely having only one object of the class, is also satisfied.
You can add your own reference counting. Whenever somebody acquires a reference with get you increase a counter and then when they won't need anymore they release it and then you decrease the counter. You can release the resource each time when reference count is 0 and reallocate when it increased to one, or just simply throw an exception, when somebody tries to release the resource when the reference count is larger then 0.
The right answer depends on exactly when you want the critical resource to be acquired, and when you want it to be released. Do you want it to happen only once, or do you want it to happen every time a client uses your Foo object? What happens if there are multiple threads? If you describe the behavior you need, then we can help you implement it.
Maneesh Godbole wrote:
I do not understand why you need to call destroy in the first place.
Suppose this critical resource is a socket. Now this socket is created only once. Now we would want a method where this socket can be closed properly and may be send a message to the socket peer that notifies the ending of session. That is why we need such a function.
Ernest Friedman-Hill wrote:The right answer depends on exactly when you want the critical resource to be acquired, and when you want it to be released. Do you want it to happen only once, or do you want it to happen every time a client uses your Foo object? What happens if there are multiple threads? If you describe the behavior you need, then we can help you implement it.
I want to acquire this critical resource to be acquired/created only once, that is when the Foo object is being created. Since this would be synchronized, I don't think having multiple threads should create any issues. Similarly this resource should be released only when e.g. the application is being closed.
I may have not understood the "Singleton" pattern completely. Most of the documentation describe only the creation aspect of a Singleton class, but are silent on the destroy aspect.
Ranjan Sinha wrote:Most of the documentation describe only the creation aspect of a Singleton class, but are silent on the destroy aspect.
That's a great catch I would say. Hardly they speak about destruction. I agree. May be due to the fact that there would be ONLY ONE object existing (if there are no break throughs in the way the singleton object is created) and it would for sure get ceased during the regular way of destroying based on the following:
1. The object reference is made point to NULL
2. The application gets removed from the Application/Web Server
3. The App/Web server gets shut down. (stopped).
Does that make sense?
In your case, as this seems to be considerate, you can very well have a check and close. Conditional Destruction as it was suggested in the initial sections of this page/post.