1

I have a question about stateless singletons. I also have a question about singletons with state.

Stateless singleton services are a good way to help with scalability. The programmer who architected the project which I maintain basically said there'll be no concurrency issues because "it is just code" (the Singleton class, that is). Meaning the class has no class level variables. It is just methods.

This is where my knowledge of C# gets a little hazy. Is there any possible issue where 2 users, via separate web requests, hit the stateless singleton at the same time? Could they end up in the same method at the same time? Is that even possible? If so, does that mean they'd be using the same local variables in that method? Sounds like a big mess, so I'm assuming it just can't happen. I'm assuming that somehow method calls are never polluted by other users.

I've asked many colleagues about this and no-one knows the answer. So it is a tricky issue.

My question about singletons generally is whether there is any problem with 2 or more concurrent users reading a public property of a Singleton. I'm only interested in reads. Is there a possibility of some kind of concurrency exception where a property is not inside a lock block? Or are concurrent, simultaneous reads safe? I don't really want to use the lock keyword, as that is a performance hit that I don't need.

Thanks

onefootswill
  • 3,707
  • 6
  • 47
  • 101
  • 1
    Stateless is good for concurrency; singletons aren't good for anything except creating global variables. Google expunges singletons from their code base. Why are you insisting on propagating them? – duffymo Apr 25 '16 at 14:00
  • 5
    If two calls to the same method are made at the same time each call will have it's own stack with it's own set of local variables. You only have to worry about concurrence with shared variables. – juharr Apr 25 '16 at 14:04
  • You say "web request", is this asp.net thing? [`Lazy<>` singleton](http://csharpindepth.com/Articles/General/Singleton.aspx#lazy) is thread-safe (rest of your question I simply don't understand). – Sinatr Apr 25 '16 at 14:04
  • @duffymo I've been working with Services that have a Singleton lifetime for a year now. It seems to work well and is not hard to work with. You just need to remember not to add any state when adding new methods. I don't think they are bad in all circumstances and they definitely minimize the memory footprint as traffic ramps up. – onefootswill Apr 25 '16 at 14:04
  • @Sinatr you should read juharr's comment if you don't understand the question. His answer may clarify what I was trying to ask. – onefootswill Apr 25 '16 at 14:06
  • @juharr Thanks. That is how I thought it worked. I just wanted to double-check to make sure they got their own stacks and were compartmentalized as such. I guess a bit of compiler knowledge would have helped here. Thanks! – onefootswill Apr 25 '16 at 14:08
  • 1
    If your service is a cloud based micro service, you might find that you want multiple instances when heavy load demands it. Your cloud might spin up multiple instances to handle the rush, then let them go out of service once it's over. What does "singleton" mean then? The key thing is stateless. Sorry, Singleton would be voted off the GoF island if this were an episode of "Survivor". One more point: singleton or no is meaningless for performance. It's the implementation and what's done that determines that. – duffymo Apr 25 '16 at 14:26
  • @duffymo I'll have to defer to your experience there. I've never used a micro service. So long as there are no concurrency issues, I think I have my answer. And I'll certainly cogitate on the views that have been expressed here. – onefootswill Apr 25 '16 at 14:37

1 Answers1

2

Singleton is an anti-pattern. A stateless singleton is even worse. If something does not hold state, there is not even the faintest reason to make it a singleton.

A stateless singleton is a pure static function from someone who enjoyed adding a pattern without thinking about what the pattern would achieve. Because in this case, he would have noticed that it achieves nothing.

If you see a stateless singleton, you can safely remove every bit of code that makes it a singleton. Add a static to the class definition. Done. Way better than before.

I think you are pretty confused about multi threading, singleton or not. I suggest you read a good book or tutorial on this because it's way out of scope for a simple answer here. If you have shared resources (simple example, a variable that is not a local) then you need to take special care in multi-threaded environments.

If you are reading more often than writing, using a ReaderWriterLock instead of a simple lockmight be beneficial. See here.

Community
  • 1
  • 1
nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • 1
    you have declared a legitimate design pattern to be an anti-pattern. Regardless of the situation or context, it is an anti-pattern, with no exceptions. I'm sorry, but I disagree. Care must be taken with singletons. But I don't think they are outright anti-patterns. – onefootswill Apr 25 '16 at 14:15
  • Singleton, even at it's best, is a pattern to constrain the user to have only *one* instance of a class. I have not found any use for this, ever. If I want only one, I will instantiate only one. It's not like I create SingletonInt classes if my program only uses a single int. Constraining the instance creation of a class that has no state and therefore no reason to be instantiated *at all* is a prime example of how misused this pattern has become. It's not the pattern that people use, it's the excuse to have a global that they need. – nvoigt Apr 25 '16 at 14:21
  • Thanks for your views. I do value the responses I get. I can see the point of Singleton services and someone recently told me that StackOverflow itself uses Singleton services (I need to verify the source of that). You have one instance and it just holds methods which get invoked. Whatever state there is, it is passed through the parameters of the methods. It is definitely easier to scope a service to a request (via an IOC) and give it state. I think the whole idea is to minimize the memory footprint and using 1 instance achieves that. In any case, it is certainly not a global variable – onefootswill Apr 25 '16 at 14:34
  • 1
    I'm not talking about the "Singleton" lifetime of an IOC. That's fine. That's no different from a normal class with a single instance. I'm talking about explicitly implementing the pattern. *That* is an anti-pattern. – nvoigt Apr 25 '16 at 14:36
  • 1
    ah, ok. I should clarify that the singleton I'm referring to is an object which has been resolved by an IOC with a Singleton lifetime. So, not scoped to a single request and it lives on, one of a kind, until the app pool recycles or whatever else may bring the appdomain down. – onefootswill Apr 25 '16 at 14:40