• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Best way to refresh a singleton using synchronization?

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 139
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.


 
Ranch Hand
Posts: 443
3
Eclipse IDE C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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.
 
Greenhorn
Posts: 14
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Saloon Keeper
Posts: 15490
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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).
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic