zoukankan      html  css  js  c++  java
  • Semaphore的应用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace SynchronizationContext
    {
        internal interface IQueueReader<T> : IDisposable
        {
            T Dequeue();
            void ReleaseReader();
        }
    
        internal interface IQueueWriter<T> : IDisposable
        {
            void Enqueue(T data);
        }
    
        internal class BlockingQueue<T> : IQueueReader<T>, IQueueWriter<T>, IDisposable
        {
            // use a .NET queue to store the data
            private Queue<T> mQueue = new Queue<T>();
            // create a semaphore that contains the items in the queue as resources.
            // initialize the semaphore to zero available resources (empty queue).
            private Semaphore mSemaphore = new Semaphore(0, int.MaxValue);
            // a event that gets triggered when the reader thread is exiting
            private ManualResetEvent mKillThread = new ManualResetEvent(false);
            // wait handles that are used to unblock a Dequeue operation.
            // Either when there is an item in the queue
            // or when the reader thread is exiting.
            private WaitHandle[] mWaitHandles;
    
            public BlockingQueue()
            {
                mWaitHandles = new WaitHandle[2] { mSemaphore, mKillThread };
            }
            public void Enqueue(T data)
            {
                lock (mQueue)
                {
                    mQueue.Enqueue(data);
                    //mQueue.Enqueue(data);//test
                }
                // add an available resource to the semaphore,
                // because we just put an item
                // into the queue.
                mSemaphore.Release();
                //mSemaphore.Release(2);//test
            }
    
            public T Dequeue()
            {
                // wait until there is an item in the queue
                WaitHandle.WaitAny(mWaitHandles);
                lock (mQueue)
                {
                    if (mQueue.Count > 0)
                        return mQueue.Dequeue();
                }
                return default(T);
            }
    
            public void ReleaseReader()
            {
                mKillThread.Set();
            }
    
    
            void IDisposable.Dispose()
            {
                if (mSemaphore != null)
                {
                    mSemaphore.Close();
                    mQueue.Clear();
                    mSemaphore = null;
                }
            }
        }
    }

    出处:http://www.codeproject.com/Articles/32113/Understanding-SynchronizationContext-Part-II

    namespace SynchronizationContext
    {
        class Program
        {
            static void Main(string[] args)
            {
                BlockingQueue<string> bq = new BlockingQueue<string>();
                //线程t1向bq中延迟插入数据
                Thread t1 = new Thread(() => { Thread.Sleep(4000); bq.Enqueue("test"); });
                t1.Start();
                //在t1将test加入到bq前,这个操作被阻塞4s左右
                string d = bq.Dequeue();
                Console.WriteLine("d:" + d);
                //Semaphore使用保证了队列中没有东西的时候出出队列的操作都是阻塞的
                string d2 = bq.Dequeue();
                Console.WriteLine("d2:" + d2);
                string d3 = bq.Dequeue();
                Console.WriteLine("d3:" + d3);
            }
        }
    }
    作者:zhanjindong
    出处:http://www.cnblogs.com/zhanjindong
    个人博客:http://zhanjindong.com
    关于:一个程序员而已
    说明:目前的技术水平有限,博客定位于学习心得和总结。
  • 相关阅读:
    转:史上最最佳软件开发实践指导
    django--rtbac权限管理
    爬虫之selenium模块
    爬虫之request模块
    爬虫基础概念
    django--cookie与session
    python--深浅copy
    基于JaCoCo的Android测试覆盖率统计(二)
    jacoco统计Android手工测试覆盖率并自动上报服务器
    macOS10.12部署sonarqube5.6.3
  • 原文地址:https://www.cnblogs.com/zhanjindong/p/2978375.html
Copyright © 2011-2022 走看看