zoukankan      html  css  js  c++  java
  • 游戏大厅 从基础开始(7)绕回来细说聊天室(中间偏下)之女仆编年史2

    老少爷们儿反击战

    上一篇中 我们的女仆终于可以做一些像阳光下其他人一样的事情了,少爷们可以和女仆酱一起参加下午茶~ 难得的上流社会啊

    这是永远1v1被人私有的女奴 喝茶时被人共有的女仆酱最明显的差异~

    明媚的午后阳光下,庭院里白色长餐桌两旁,英俊的少爷们彼此交换着最近的趣闻轶事,一面欣赏女仆酱以1/3几率打翻茶水,可爱而笨笨地努力侍奉着,闪闪发光的样子。

    人间极乐喵~~~~~~~~~~   :3

    但距离真正的自由~~无Lock还是很远,很远。

    因为,

    老爷和少爷的调教仍然是一如既往的频繁! 女仆酱你仍然是伟大的老少爷们的东西~!

    我们看上一次所说的调用聊天室方式:

    Code Snippet
    1.        Channel cr = session["Chat"];
    2.             cr.Say(Request["text"]);
    3.             foreach (var s in cr.Listen())
    4.             {
    5.                 Response.write("<p>");
    6.                 Response.write(s);
    7.                 Response.write("</p>");
    8.             }

    这个行程可不得了

    1. 女仆来~~ (get instance)
    2. 调教~!(Say & writelock)
    3. 喝茶~!(Listen & readlock)

    所有的少爷和老爷都是这个行程  执事先生,您是恶魔执事来的吧!(塞巴斯酱邪媚一笑)

    虽然效率高了近一倍,但是 在奉茶的时候 仍然有调教的队伍大排长龙~

    image

    这让老少爷们很是不 不不爽 ! “主人样”们是不会这样满足地口胡!~ 啊 太激动了,咽口水先。

    -------------------------------------------------------------------------------------

    最年轻的少爷在某个风和日丽的下午茶时间 提出了一个邪恶点子:

    “既然我们喝茶的时候只是想看着女仆酱,又不是真的希望她倒茶,为啥我们不能一边看着别人调教女仆酱  一边喝茶呢?”

    全体老少爷们的红茶都化作血雾喷洒在无瑕的桌上,纷纷气绝。

    小少爷解释道:

    既然数据池实际上是一个队列  而加入队列仅仅是对队列头有所操作,

    那么在已经访问过的节点另一端加入的内容 对于已经开始访问内部内容的线程来说是毫无意义的

     image

    为了“不存在”的变化加锁,这又是何苦呢?

    “囊得斯嘎!?”

    “艘得斯嘎!!”

    “游息!!”

    爬起来的各位纷纷恍然大悟装,激动地握住彼此的手,泛着泪光。。。。

    可是为什么我们之前要加锁呢?

    深入研究Queue<T> 的源代码  我们了解到 Queue<T>的实现方法:定长数组实现的循环队列

    不熟悉循环队列的兄弟们可以参考博友刺儿头的文章

    当每次 ToArray的时候 Queue<T>执行下面的操作

    Code Snippet
    1.         public T[] ToArray()
    2.         {
    3.             T[] destinationArray = new T[this._size];
    4.             if (this._size != 0)
    5.             {
    6.                 if (this._head < this._tail)
    7.                 {
    8.                     Array.Copy(this._array, this._head, destinationArray, 0, this._size);
    9.                     return destinationArray;
    10.                 }
    11.                 Array.Copy(this._array, this._head, destinationArray, 0, this._array.Length - this._head);
    12.                 Array.Copy(this._array, 0, destinationArray, this._array.Length - this._head, this._tail);
    13.             }
    14.             return destinationArray;
    15.         \

    同时有人Enqueue的时候  _size _head  _tail 都可能被并发修改

    Code Snippet
    1.     public void Enqueue(T item)
    2.         {
    3.             if (this._size == this._array.Length)
    4.             {
    5.                 int capacity = (int)((this._array.Length * 200L) / 100L);
    6.                 if (capacity < (this._array.Length + 4))
    7.                 {
    8.                     capacity = this._array.Length + 4;
    9.                 }
    10.                 this.SetCapacity(capacity);
    11.             }
    12.             this._array[this._tail] = item;
    13.             this._tail = (this._tail + 1) % this._array.Length;
    14.             this._size++;
    15.             this._version++;
    16.         }

    太危险了!

    我们是为了保障这些关键标记量才用的Lock  这是数组内核本身限制造成的:( 

    我们一开始就陷入了  “要用队列,M$提供了队列”的心理陷阱,

    ——果然观赏女仆酱一定要喝茶是错误的常识

    ——看来聊天数据池还真的不能拿来主义

    对于微软类库做不到的 我们一定要有自己的实现。 所以女仆酱啊,你的末日到了欧欧欧欧喝喝喝喝喝喝HiaHiaHia …..

    敬请期待下一篇:

    垃圾列表

  • 相关阅读:
    WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构
    WCF后续之旅(13): 创建一个简单的WCF SOAP Message拦截、转发工具[上篇]
    Enterprise Library深入解析与灵活应用(6):自己动手创建迷你版AOP框架
    [原创]WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿
    WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成
    WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘
    谈谈基于SQL Server 的Exception Handling
    Is this a MS EnterLib DAAB BUG or not?
    难道调用ThreadPool.QueueUserWorkItem()的时候,真是必须调用Thread.Sleep(N)吗?
    WCF中的Binding模型之一: Binding模型简介
  • 原文地址:https://www.cnblogs.com/waynebaby/p/1552206.html
Copyright © 2011-2022 走看看