文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>多线程学习-线程同步,lock初探

多线程学习-线程同步,lock初探

时间:2010-10-01  来源:伊羽

为了防止共享资源被多个线程破坏,就必须在代码中使用线程同步结构。

比如现在有一个计数器,每次访问都加1

    public sealed class NormalCounter
    {
        Int32 num = 0;

        public void Add()
        {
            num++;
        }

        public Int32 GetNumber
        {
            get
            {
                return num;
            }
        }
    }

现在有3个不同的用户同时访问这个计数器(3个线程)

 

    public class TestNormalCounter
    {
        public void StartWithMultiThread()
        {
            new Thread(() => { JustDoIt(); }).Start();
            new Thread(() => { JustDoIt(); }).Start();
            new Thread(() => { JustDoIt(); }).Start();
        }

        void JustDoIt()
        {
            NormalCounter counter = new NormalCounter();
            for (Int32 i = 0; i < 5; i++)
            {
                counter.Add();
                Console.WriteLine(String.Concat("由ID是:", Thread.CurrentThread.ManagedThreadId, " 的线程输出当前值:", counter.GetNumber));
            }
        }
    }

最后结果如下:

并没有达到计数器的效果,这是因为创建了3个实例,系统分配了3块内存分别进行了计数。

为了避免这种情况,就要线程同步结构。

public sealed class SingletonCounter
    {
        static SingletonCounter counter = null;
        static readonly Object thislock = new Object();

        Int32 num = 0;

        SingletonCounter() { }

        public static SingletonCounter GetCounter
        {
            get
            {
                if (null == counter)
                {
                    lock (thislock)
                    {
                        counter = new SingletonCounter();
                    }
                }
                return counter;
            }
        }

        public void Add()
        {
            num++;
        }

        public Int32 GetNumber
        {
            get
            {
                return num;
            }
        }
    }
  //测试代码跟前一实例一样

这里用到了双检锁技巧来保证整个程序中,只有一个SingletonCounter实例,这样计数器便能正确的运行

(这里用到了单例设计模式,单例设计模式实际只需要用静态初始化,或者嵌套类延时初始化就可以简单的实现,这里只是演示如何使用lock来做同步)

结果如下:

 

lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
      如果实例可以被公共访问,将出现 lock (this) 问题。
      如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
      由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。
最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载