C# 多线程共享计数器和列表集合变量

C# 多线程共享计数器和列表集合变量,c#,multithreading,C#,Multithreading,在这个场景中,我有多个线程试图共享一个静态全局变量计数器。 之后,我将它添加到一个整数列表中,这个列表将在另一个线程中用于检查一些细节 我意识到即使在全局变量计数器上使用锁,我仍然会得到重复的数字 请原谅我的解释,代码会说明更多 问题是不同的线程可能会生成相同的计数器值(我不想要)。 我想要一个不重复的连续号码 class Test { private Object _thisLock = new Object(); List<int> listing = new L

在这个场景中,我有多个线程试图共享一个静态全局变量计数器。 之后,我将它添加到一个整数列表中,这个列表将在另一个线程中用于检查一些细节

我意识到即使在全局变量计数器上使用锁,我仍然会得到重复的数字

请原谅我的解释,代码会说明更多

问题是不同的线程可能会生成相同的计数器值(我不想要)。 我想要一个不重复的连续号码

class Test
{
    private Object _thisLock = new Object();
    List<int> listing = new List<int>(); //shared LIST

    public void Main()
    {
        //array of threads
        for (int i = 0; i < 8; i++)
        {
            Thread th = new Thread(Work);
            th.Name = "Thread" + i;
            th.Start();
        }
        Thread.Sleep(5000);
        //Start checking for duplicates
        Thread checker = new Thread(Checker);
        checker.Start();
    }

    private void Work()
    {
        Object _thisLock = new Object();
        while (true)
        {
            int a = Singleton.Instance.Counter++;
            Console.WriteLine(Thread.CurrentThread.Name);
            Console.WriteLine("WOrk : " + a);
            lock (_thisLock)
            {
                listing.Add(a);
            }
            Thread.Sleep(1000);
        }
    }

    private void Checker()
    {
        Object _thisLock = new Object();
        while (true)
        {
            lock (_thisLock)
            {
                List<int> selflist = new List<int>();
                selflist.AddRange(listing); ;

                foreach (int p in selflist)
                {

                    if (selflist.FindAll(item => item.Equals(p)).Count() > 1)
                    {
                        Console.WriteLine("Check!!!!!!!!!!!!!!!!!! : " + p);
                    }
                }
            }


            Thread.Sleep(5000);
        }
    }
}

static void Main()
{
    Test t = new Test();
    t.Main();
}

public sealed class Singleton
{
    private static volatile Singleton instance;
    private static object syncRoot = new Object();
    private readonly Object _thisLock = new Object();

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new Singleton();
                }
            }

            return instance;
        }
    }
    private volatile static int _counter;
    public int Counter
    {
        get
        {
            lock (_thisLock)
            {
                return _counter;
            }
        }
        set
        {
            lock (_thisLock)
            {
                _counter = value;
            }
        }
    }
}
类测试
{
私有对象_thisLock=新对象();
列表列表=新列表();//共享列表
公共图书馆
{
//线程数组
对于(int i=0;i<8;i++)
{
螺纹th=新螺纹(工件);
th.Name=“Thread”+i;
th.Start();
}
睡眠(5000);
//开始检查重复项
螺纹检查器=新螺纹(检查器);
checker.Start();
}
私人工作()
{
对象_thisLock=新对象();
while(true)
{
inta=Singleton.Instance.Counter++;
Console.WriteLine(Thread.CurrentThread.Name);
控制台写入线(“工作:+a”);
锁(这个锁)
{
增列(a);
}
睡眠(1000);
}
}
专用无效检查器()
{
对象_thisLock=新对象();
while(true)
{
锁(这个锁)
{
List selflist=新列表();
selflist.AddRange(列表);
foreach(自我列表中的int p)
{
if(selflist.FindAll(item=>item.Equals(p)).Count()>1)
{
控制台。写线(“检查!!!!!!!!!!!:”+p);
}
}
}
睡眠(5000);
}
}
}
静态void Main()
{
测试t=新测试();
t、 Main();
}
公共密封类单件
{
私有静态易失性单例实例;
私有静态对象syncRoot=新对象();
私有只读对象_thisLock=新对象();
私有单例(){}
公共静态单例实例
{
收到
{
if(实例==null)
{
锁定(同步根)
{
if(实例==null)
instance=newsingleton();
}
}
返回实例;
}
}
专用易失性静态整数计数器;
公共整数计数器
{
收到
{
锁(这个锁)
{
返回计数器;
}
}
设置
{
锁(这个锁)
{
_计数器=值;
}
}
}
}

为什么不将计数器移动到
锁中,并通过将其移动到类级别来共享锁

private object _thisLock = new object();

...

lock (_thisLock)
{
    int a = Singleton.Instance.Counter++;
    listing.Add(a);
}

另外,使用线程安全的集合类型,例如。

为什么不将计数器移动到
锁中,并通过将其移动到类级别来共享锁

private object _thisLock = new object();

...

lock (_thisLock)
{
    int a = Singleton.Instance.Counter++;
    listing.Add(a);
}

另外,使用线程安全的集合类型,如。

工作方法中,每个线程都有自己的锁对象
\u thisLock
。 在工作方法中删除此语句,并让它使用类的私有lockobject:

Object _thisLock = new Object();

工作
方法中,每个线程都有自己的锁对象
\u此锁
。 在工作方法中删除此语句,并让它使用类的私有lockobject:

Object _thisLock = new Object();

我会尝试一下,因为我运行的是框架3.5,我没有ConCurrentBag。我会尝试一下,因为我运行的是框架3.5,我没有ConCurrentBag