1
\$\begingroup\$

I need to generate a sequence of int values: { 0, 1, 2, ... }, but there's a twist: I need to access them from different threads.

So I wrote this code:

class Counter
{
    private static Counter instance = new Counter();
    private static int i = 0;

    public static Counter Instance
    {
        get
        {
            return instance;
        }
    }

    public int Next()
    {
        lock (this)
        {
            return i++;
        }
    }

    public void Reset()
    {
        lock (this)
        {
            i = 0;
        }
    }

}

May this be implemented in a simpler way?

\$\endgroup\$
4
  • \$\begingroup\$ Your code looks quite simple, readable and obvious to me (ignoring the unnecessary singleton “noise”). Why do you want to do it even simpler? \$\endgroup\$
    – svick
    Commented May 6, 2012 at 17:12
  • \$\begingroup\$ @svick also I expect that probably lock can be avoided somehow, probably c# has built-in synchronized int or something? \$\endgroup\$ Commented May 7, 2012 at 5:05
  • \$\begingroup\$ @javapowered, yes, C# has something like that, but it's quite hard to get right. So, unless this code is a performance bottleneck for you, you should probably stick with lock. \$\endgroup\$
    – svick
    Commented May 7, 2012 at 9:01
  • \$\begingroup\$ I think Interlocked.Increment is what you're looking for. \$\endgroup\$ Commented May 7, 2012 at 11:59

2 Answers 2

2
\$\begingroup\$
private static int i = 0;

Are you sure that i should be static? If it's static there isn't too much sense of the Counter instance = new Counter() instance and the Next and the Reset methods also could be static.

Anyway, I'd use a longer variable name, like nextValue for better readability.

Furthermore, consider the drawbacks of the Singleton pattern:

This pattern makes unit testing far more difficult, as it introduces global state into an application.

More on Wikipedia.

\$\endgroup\$
0
\$\begingroup\$

Never lock on this as your callers can also do the same and cause deadlocks where you don't expect them. See below where I create and use a private locking variable. And made i an instance variable since you use a singleton instance anyhow.

class Counter
{
    private static readonly Counter instance = new Counter();

    private static readonly object locker = new object();

    private int i;

    public static Counter Instance
    {
        get
        {
            return instance;
        }
    }

    public int Next()
    {
        lock (locker)
        {
            return i++;
        }
    }

    public void Reset()
    {
        lock (locker)
        {
            i = 0;
        }
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ this code doesn't look simpler, I know that it is not recomended to lock on this but it's fine for such small simple and rarely used class imho. \$\endgroup\$ Commented May 7, 2012 at 13:52
  • 1
    \$\begingroup\$ Never claimed it was simpler -- just making it work properly. That's the first step before trying to simplify. \$\endgroup\$ Commented May 7, 2012 at 13:53
  • 1
    \$\begingroup\$ Nitpicking: lock (locker) makes me think of a box that contains a secret that one locks. I would call it something else ... maybe lockHandle, like Bill Wagner does informit.com/articles/article.aspx?p=1231461 \$\endgroup\$
    – Leonid
    Commented May 7, 2012 at 13:57
  • \$\begingroup\$ Hm.. I can buy that locker isn't a good name, but I really detest things with handle in them when they're not actually handles, either. lockingObject, monitor (since lock expands to Monitor.Enter and Monitor.Exit), sync ?? \$\endgroup\$ Commented May 7, 2012 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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