This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Threads and Synchronization and the fly likes Best way to refresh a singleton using synchronization? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Best way to refresh a singleton using synchronization?" Watch "Best way to refresh a singleton using synchronization?" New topic
Author

Best way to refresh a singleton using synchronization?

Derrick Williams
Greenhorn

Joined: Nov 27, 2010
Posts: 9
I have to say every day I learn something new here, I hope to be good enough in Java to contribute more someday!

I have a question about what would be the best way to solve a concurrency problem I'm having. Here's the problem statement as concise as I can make it:

The FrobNozz application stores WhizzBang data into a singleton Collection from a data feed. Many methods read from the WhizzBang Collection. Now and then the Collection needs to be refreshed with new WhizzBang data. What's the best way to deal with processes using the methods?

The structure in Pseudocode:




Just an example, whizzData's not always a List, it could be some other Collection (Hashmap, Queue, etc). When new data is available, "whizzData" is set to null, causing it to pull in new data. Checking for 'null' twice (as I understand it) checks this condition just in case a bunch of threads hit the initial 'null' check at once.

My problem is that there are a huge amount of functions that slice and dice the whizzData singleton (all strictly read operations, which simplifies it a bit). Obviously for the interests of speed, I don't synchronize any of these methods, but if 'whizzData' is updated, the threads in the slice-and-dice functions just go bonkers, as 'whizzData" changes in the middle of processing. Stacktraces everywhere. Not a pretty sight. "whizData" isn't updated very often, maybe two or three times a day at the very most.

So is there a way to say "everybody out of the pool!", let all the threads finish executing the slice-and-dice methods, but prevent new threads from entering the methods. Once all the threads have exited the methods, I could update "whizzBang", then blow the whistle and let all the threads go back to using the methods?

I am sure I am probably approaching the problem through brute force, and there is a simpler and more elegant way to do this kind of update. How would you do it?

Thanks a bunch!

-Derrick
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12756
    
    5
Seems to me that since replacing a reference is atomic, you could prepare a new collection at your leisure and store the new whizzData when it is ready.

If you had your code that works with whizzData a reference to the current value which it keeps locally instead of having it repeatedly retrieve whizzData then that code can continue working with the old data. Eventually all references to the old collection will be lost and it will be GCed.

Bill
John Vorwald
Ranch Hand

Joined: Sep 26, 2010
Posts: 139
I'm a newbie to threads, so I need to write code to represent the problem / solution. I think the following code simulates what you are trying to do.


Chris Hurst
Ranch Hand

Joined: Oct 26, 2003
Posts: 407
    
    1



I'm having dejavu with the double checked idiom .. if this is meant to be thread safe its not.



is unsafe, its not static final (which it can't be) or volatile.

Apologies if I have this wrong I'm just giving the code a quick scan but it looks wrong.


"Eagles may soar but weasels don't get sucked into jet engines" SCJP 1.6, SCWCD 1.4, SCJD 1.5,SCBCD 5
Vladimir Ozerov
Greenhorn

Joined: Sep 27, 2011
Posts: 14
Derrick Williams,

1) The main thing - your code is badly wrong. What if one thread call readyForNewFeed() while another one is currently processing analyzeThis() method? For sure the second one will fail.
2) The second main thing - one of the gold programming rules says "first make it right then make it efficient". You haven't made your code right yet, but already trying to optimize it. Why do you think that inroduction of "synchronized" will cause unacceptable performance degradation? Have you tried to measure the negative effect? Are there any point in your requirements regarding perfmrance? You should never avoid threads synchronization until it is proven to be unacceptable according to your requirements.
3) If your only problem is how to safely recreate the object, then your choice is a ReadWriteLock. Using this lock you will allow concurrent read operations and on the object, but will disallow concurrent read and object recreation. This is how your code might looks like in this case:
4) You use double check anitpattern. You must get rid of it!
5) Why do you really need to recreate the object? Why don't you want to simply clear it? The pair of methods getWhizzData() and readyForNewFeed() smells a lot! Think on how to refactor it.

Here is the example on how your code would look like with ReadWrite lock and without double-check antipattern:

Derrick Williams
Greenhorn

Joined: Nov 27, 2010
Posts: 9

Thanks for the great replies everyone - excellent food for thought and it shows how much there is to learn about Java! I'm implementing the read/write locks and it was just the ticket. Thanks again!

-Derrick
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

And of course the first suggestion is to stop using a singleton. Its a bad design. Folks use it as a crutch, a bad habit. Don't use it.
Vladimir Ozerov
Greenhorn

Joined: Sep 27, 2011
Posts: 14
Pat Farrell,
The singleton is not bad a design pattern. It can be "bad" in case used incorrectly as any other design pattern. Therefore your advise doesn't make sense beacause either you nor anybody alse except the author know full context of the problem.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

Vladimir Ozerov wrote:The singleton is not bad a design pattern. It can be "bad" in case used incorrectly as any other design pattern.


You are entitled to your opinion. I maintain that it is a very bad pattern and its use should strongly be discouraged. It is used incorrectly more often than not. There are many alternative patterns that solve the same design question without the many evil side effects of the Singleton.

For one simple example: a Singleston is just a global wad of namespace. It encourages coupling and decreases cohesion. The point of good OO design is to decrease coupling and increase cohesion.

I could go on and on.
Vladimir Ozerov
Greenhorn

Joined: Sep 27, 2011
Posts: 14
First of all use of singleton has no relation to cohesion at all because terms "cohesion" and "singletone" are orthogonal to each other
As for coupling - yes it might affected, but 1) we don't know the context; 2) not always there is something to decouple; 3) even if there is something to decouple it doesn't mean that we have to do that every time
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

Vladimir Ozerov wrote:First of all use of singleton has no relation to cohesion at all because terms "cohesion" and "singletone" are orthogonal to each other
As for coupling - yes it might affected, but 1) we don't know the context; 2) not always there is something to decouple; 3) even if there is something to decouple it doesn't mean that we have to do that every time

As I said before, you are entitled to your own opinion, but you have zero chance of convincing me that yours is correct.

Please review the field a bit. Cohesion (wikipedia). Any Class that refers to the Singleton has low cohesion.

Its not a question that using a Singleton "might" increase coupling. By definition, every class that uses the Singleton is coupled to it. Worse, each class is strongly coupled to data from the one and only one definition/instance of the global wad of data. You can no long unit test your class, because it is strongly coupled to the singleton.

Every class that uses any data from the singleton is strongly coupled together. This is simply very bad OO design.

There are many alternatives that resolve the many issues with Singletons. I've only covered a tiny bit of the badness here. Use one of the alternatives.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3573
    
  14

The coupling is not a property of the singleton class, but that of the classes using it. Whether or not a class is a singleton is an implementation detail. From the outside it should not matter whether a factory method performs instance control or not.

So yes, classes that access a singleton through the factory method directly have high coupling. Instead, the object should be passed to them in a method parameter, even if it's always the same instance. This does not necessarily make instance control a bad thing, especially if the class is immutable.

Singletons have their place, but they are grossly over- and misused.

Take a logging facility for instance. It would be a tremendous pain to pass loggers all over the code. That's why the standard Java logging facility provides instance control and static accessors (which the singleton class is a special case of).
 
Consider Paul's rocket mass heater.
 
subject: Best way to refresh a singleton using synchronization?
 
Similar Threads
Need help understanding how to synchronize methods correctly
Singleton Class
Singleton Class
B&S v2.3.1 - Data, CacheManager and RecordNotFoundException
collections and clone()