首页 新闻 会员 周边

单例模式,有很大疑惑,望大神解释一下

0
悬赏园豆:20 [已解决问题] 解决于 2015-04-02 09:06

class Program    

{        

  static void Main(string[] args)        

  {

              Console.WriteLine("主线程开始" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

            ThreadPool.QueueUserWorkItem(obj =>

      { 

                    SingleTon single = SingleTon.GetInstence(); 

                    Console.WriteLine(single.index.ToString());

                   single.index++;                

      });

            ThreadPool.QueueUserWorkItem(obj =>                

      {

                    SingleTon single2 = SingleTon.GetInstence();

                    Console.WriteLine(single2.index.ToString());

                });

            Console.WriteLine("主线程结束" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

            Console.ReadLine();

        }

    }

 

class SingleTon

    {

        private static SingleTon singleTon;

        public int index;

        private static readonly object locker = new object();

        private SingleTon()

        {

            Console.WriteLine("创建单例当前线程" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

        }

        public static SingleTon GetInstence()

        {

            if (singleTon == null)

            {

                lock (locker)

                {

                    if (singleTon == null)

                    {

                        singleTon = new SingleTon();

                    }

                }

            }

            return singleTon;

        }

    }

 

我新建了一个单例,也自己加了一个int类型 的数据(静态的也一样),可是无论是不是加锁,是不是多线程调用,这个类型的值总是不固定的,要么0 0,要么0 1,为什么会这样?

代码小兵的成长的主页 代码小兵的成长 | 菜鸟二级 | 园豆:303
提问于:2015-04-01 20:53
< >
分享
最佳答案
0

你说的是index的值吧?

你创建了两个线程,A和B

你的A在执行的时候做了两件事:输出index,然后index增1

你的B在执行的时候只做了一件事:输出index。

所以,输出的结果是确定的,要么0,0,要0,1,同时,也是不确定的,因为可能是0 0,也可能是0 1

为什么呢?

A、B的线程虽然在定义的时候有先后,但是在执行的时候是不确定的,可能先执行A后执行B,结果就是0 1,也可能先执行B后执行A,结果就是 0 0

看下以下代码的结果:

static void Main(string[] args)        

  {

              Console.WriteLine("主线程开始" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

            ThreadPool.QueueUserWorkItem(obj =>

      { 

                    SingleTon single = SingleTon.GetInstence(); 

                    Console.WriteLine(obj.ToString() + "-" + single2.index.ToString());

                   single.index++;                

      }, "A");

            ThreadPool.QueueUserWorkItem(obj =>                

      {

                    SingleTon single2 = SingleTon.GetInstence();
    
                    Console.WriteLine(obj.ToString() + "-" + single2.index.ToString());

                }, "B");

            Console.WriteLine("主线程结束" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

            Console.ReadLine();

        }    

 

收获园豆:20
519740105 | 大侠五级 |园豆:5810 | 2015-04-01 21:22

额,多谢大神了,是我自己晕了,忘记了线程同一优先级下操作顺序也是无序的,多谢多谢,醍醐灌顶,哈哈

代码小兵的成长 | 园豆:303 (菜鸟二级) | 2015-04-02 09:05
其他回答(1)
0

没明白你问什么。

Firen | 园豆:5385 (大侠五级) | 2015-04-01 21:15

我的意思就是,我使用多线程调用单例方法,操作实体里面的一个字段,问题是操作的结果不是我想要的

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2015-04-02 09:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册