Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I hear a lot about "Singletons are always bad" around the place. I don't hate on them to that degree but I try not to use them if I have a better alternative.

In this case I have a system that handles a lot of requests, each of which comes in on its own thread. Every request that comes in needs to be allocated its own unique sequential Id.

Currently I have a Singleton class whose role is to initiate this Id at start-up then maintain it while the system runs. The Singleton is created/retrieved and the Id value incremented in a thread safe way, as one would expect. It is actually handed out to the threads on creation by Dependency Injection, but the core of the class is a classic Singleton built around a static representation of the current Id value.

Given that we are only likely to do more work that requires a multi-threaded approach, I would be interested to know whether there is a way I could implement this type of functionality in a way that allows data to be maintained synchronously across threads that are otherwise unaware of each other, without using the much feared Singleton pattern?

share|improve this question
2  
It seems like you are using the Singleton pattern precisely how it should be used. Unless you need to start scaling your application across multiple (virtual or real) machines, I wouldn't worry about it. –  Matthew Flynn Mar 20 '13 at 14:52
    
How will it work with multiple servers? Do you need to keep ID of request unique in global state or only inside one process? –  OZ_ Mar 20 '13 at 14:54
    
@OZ_ the design is currently oriented towards a single machine- although the system will operate on multiple ones there is no need for the ID to be unique across machines, just within the application. –  glenatron Mar 20 '13 at 15:09
    
It's not clear that singleton means what you think it means. Are you calling its getInstance() then injecting the result? It's also not clear why the current Id would need to be static, if you only have one instance of the class. Could you post some code? –  Karl Bielefeldt Mar 20 '13 at 15:37
    
Is it only a singleton if you obtain it by getInstance? I am using checked instantiation so there is a single static implementation of the class returned when it is called, but I don't have an explicit getInstance method. Is this behaviour significantly different? –  glenatron Mar 20 '13 at 15:58

2 Answers 2

There is a difference between a singleton and an instance that can be shared between multiple clients. You seem to want the latter (if not, think again!). For that, a singleton has no advantage and many of the usual downsides. Just permit any number of instances, but don't actually create several ones when you want sharing. You already have the infrastructure right for this (passing the object via dependency injection). You probably only need to make the constructor public and get rid of the singleton infrastructure.

So it costs practically nothing, and you gain:

  • Simplicity: Luckily, not making something a singleton is slightly easier than making it a singleton.
  • Testability: When you want to test something involving this ID allocator, you can just create a new one instead of depending on some global state of some singleton.
  • Extensibility: Should you at one point need several independent sources of sequential IDs in one process, you can just create another instance.
share|improve this answer
    
How do I guarantee that the different instances are only handing out unique and sequential ids? My singleton is already implementing an interface for DI/mocking purposes, so there isn't a problem with testing things that use it. –  glenatron Mar 20 '13 at 15:14
    
@glenatron You don't. The whole point is allowing (or rather, not explicitly prohibiting!) several completely independent instances. When you need multiple places (e.g. server threads) to get unique and sequential IDs w.r.t. to each other, you give them the same instance. –  delnan Mar 20 '13 at 15:31

By having a singleton, you're then adding the singleton creation, access and state manipulation to your multithreading concerns.

Further, you're assuming that your request handler is going to only have one in the entire system. This is incorrect. Yes, you might only need one now. But what about unit tests? Are you really not going to run them concurrently? What about sub-systems that may eventually want their own request dispatch? What about possibly decorating or compositing that dispatch?

No, you have some object that takes requests and assigns them an ID for that handler. If they change scopes, then you can either simply re-ID the request or have a single shared ID provider for your different request handlers.

share|improve this answer
    
creation can be done pre thread start-up (eager initialization) and state manip is just InterleavedIncrement –  ratchet freak Mar 20 '13 at 14:58
    
@ratchetfreak - the entire point of a singleton rather than a simple global/static is to ignore creation timing. If you then limit it to thread start-up, what's the point. And I means state of the singleton, not the ID; I'll look to clarify the answer. –  Telastyn Mar 20 '13 at 15:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.