zoukankan      html  css  js  c++  java
  • ThreadSafety with the Semaphores Class(Synchronization of .net)

    Semaphores

    A Semaphore inherits from System.Threading.WaitHandle; as such, it has the WaitOne() method. You are also able to use the static System.Threading.WaitHandleWaitAny()WaitAll()SignalAndWait() methods for more complex tasks.

    semaphores model like this. see below:

     

    I read something that described a Semaphore being like a nightclub. It has a certain capacity, enforced by a bouncer. When full, no more people can enter the club, until one person leaves the club, at which point one more person may enter the club.

    Let's see a simple example, where the Semaphore is set up to be able to handle two concurrent requests, and has an overall capacity of 5. 

    using System;
    using System;
    using System.Threading;

    namespace SemaphoreTest
    {
        class Program
        {
            //initial count to be satified concurrently = 2
            //maximum capacity = 5
            static Semaphore sem = new Semaphore(2, 5);

            static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    new Thread(RunThread).Start("T" + i);
                }

                Console.ReadLine();
            }

            static void RunThread(object threadID)
            {
                while (true)
                {
                    Console.WriteLine(string.Format(
                        "thread {0} is waiting on Semaphore", 
                        threadID));
                    sem.WaitOne();

                    try
                    {
                        Console.WriteLine(string.Format(
                            "thread {0} is in the Semaphore, and is now Sleeping", 
                            threadID));
                        Thread.Sleep(100);
                        Console.WriteLine(string.Format(
                            "thread {0} is releasing Semaphore", 
                            threadID));
                    }
                    finally
                    {
                        //Allow another into the Semaphore
                        sem.Release();
                    }
                }
            }
        }

    }

    Which results in something similar to this: 

     

    This example does show a working example of how a Semaphore can be used to limit the number of concurrent threads, but it's not a very useful example. I will now outline some partially completed code, where we can use aSemaphore to limit the number of threads trying to access a database with a limited number of connections available. The database can only accept a maximum of three concurrent connections. As I say, this code is incomplete, and does not work in its current state; it's for demonstration purposes only, and is not part of the attached demo app. 
    using System;
    using System.Threading;
    using System.Data;
    using System.Data.SqlClient;

    namespace SemaphoreTest
    {
        /// <summary>
        /// This example shows partially completed skeleton
        /// code for consuming a limited resource, such as a
        /// DB connection using a Semaphore
        /// 
        /// NOTE : THIS CODE WILL NOT RUN, ITS INCOMPLETE
        ///        DEMO ONLY CODE
        /// </summary>
        class RestrictedDBConnectionStringAccessUsingSemaphores
        {

            //initial count to be satified concurrently = 1
            //maximum capacity = 3
            static Semaphore sem = new Semaphore(1, 3);

            static void Main(string[] args)
            {
                //start 5 new threads that all require a Database connection
                //but as a DB connection is limited to 3, we use a Semaphore
                //to ensure that the number of active connections will never
                //exceed the total allowable DB connections
                new Thread(RunCustomersThread).Start("ReadCustomersFromDB");
                new Thread(RunOrdersThread).Start("ReadOrdersFromDB");
                new Thread(RunProductsThread).Start("ReadProductsFromDB");
                new Thread(RunSuppliersThread).Start("ReadSuppliersFromDB");
                Console.ReadLine();
            }

            static void RunCustomersThread(object threadID)
            {
                //wait for the Semaphore
                sem.WaitOne();
                //the MAX DB connections must be within its limited
                //so proceed to use the DB
                using (new SqlConnection("<SOME_DB_CONNECT_STRING>"))
                {
                    //do our business with the database
                }
                //Done with DB, so release Semaphore which will
                //allow another into the Semaphore
                sem.Release();
            }

            static void RunOrdersThread(object threadID)
            {
                //wait for the Semaphore
                sem.WaitOne();
                //the MAX DB connections must be within its limited
                //so proceed to use the DB
                using (new SqlConnection("<SOME_DB_CONNECT_STRING>"))
                {
                    //do our business with the database
                }
                //Done with DB, so release Semaphore which will
                //allow another into the Semaphore
                sem.Release();
            }

            static void RunProductsThread(object threadID)
            {
                //wait for the Semaphore
                sem.WaitOne();
                //the MAX DB connections must be within its limited
                //so proceed to use the DB
                using (new SqlConnection("<SOME_DB_CONNECT_STRING>"))
                {
                    //do our business with the database
                }
                //Done with DB, so release Semaphore which will
                //allow another into the Semaphore
                sem.Release();
            }

            static void RunSuppliersThread(object threadID)
            {
                //wait for the Semaphore
                sem.WaitOne();
                //the MAX DB connections must be within its limited
                //so proceed to use the DB
                using (new SqlConnection("<SOME_DB_CONNECT_STRING>"))
                {
                    //do our business with the database
                }
                //Done with DB, so release Semaphore which will
                //allow another into the Semaphore
                sem.Release();
            }
        }

    }

    From this small example, it should be clear that the Semaphore only allows a maximum of three threads (which was set in the Semaphore constructor), so we can be sure that the database connections will also be kept within limit. 
  • 相关阅读:
    打印从1到最大的n位数
    TCP/IP协议
    函数指针做函数参数
    Ubuntu系统扩大/home分区
    《一切都准时》一首非常有意思的小诗
    阿里云服务器编译安装Hadoop 2.7.4 伪分布式环境
    C++中的string类型占用多少个字节
    使用apt-file安装需要的软件包或者库文件
    剑指offer之【表示数值的字符串】
    剑指offer之【正则表达式】☆
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2532249.html
Copyright © 2011-2022 走看看