Thread-Safety with the Semaphores Class(Synchronization of .net)
2012-06-02 21:38
375 查看
Semaphores
A Semaphore inherits fromSystem.Threading.WaitHandle; as such, it has the
WaitOne()method. You are also able to use the static
System.Threading.WaitHandle,
WaitAny(),
WaitAll(),
SignalAndWait()methods for more complex tasks.
semaphores model like this. see below:
![](http://images.cnblogs.com/cnblogs_com/malaikuangren/semQueue.png)
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:
![](http://images.cnblogs.com/cnblogs_com/malaikuangren/semaphore.png)
This example does show a working example of how a
Semaphorecan 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 a
Semaphoreto 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
Semaphoreonly allows a maximum of three threads (which was set in the
Semaphoreconstructor), so we can be sure that the database connections will also be kept within limit.
相关文章推荐
- Thread-Safety with the Interlocked Class(Synchronization of .net)
- Thread-Safety with the AutoResetEvent, ManualResetEvent Class(Synchronization of .net)
- Thread-Safety Mutex vs Lock(Synchronization of .net)
- AS.NET2.0 用户控件错误!!The base class includes the field 'MyControl_1', but its type (MyControl) is not compatible with the type of control (ASP.MyControl_ascx).
- Thread-Safety Read Write Lock(Synchronization of .net)
- ASP.NET操作EXCEL时出现的错误 Retrieving the COM class factory for component with CLSID
- org.hibernate.WrongClassException: Object with id: 3 was not of the specified subclass
- The web application created a ThreadLocal with key of type [null] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@1807b9
- ASP.NET操作EXCEL时出现的错误 Retrieving the COM class factory for component with CLSID(转)
- 使用JavaScript展开/折叠TreeView中所有节点(Expand and Collapse All Nodes of asp.net Treeview on the client with javascript)
- 关于The web application [/cdmaPlus] created a ThreadLocal with key of type
- the schema version of 'microsoft.aspnet.mvc' is incompatible with version of nuget
- ASP.NET操作EXCEL时出现的错误 Retrieving the COM class factory for component with CLSID(转)
- The .NET Framework includes a set of standard class libraries
- Thread-safety with the Java final keyword
- The base class includes the field '...', but its type (...) is not compatible with the type of control (...)
- The web application [/XinRui02] created a ThreadLocal with key of type [com.opensymphony.xwork2.inje
- Creating An Instance Of The Com Component With Clsid {b9425246-4131-11d2-be48-004005a04edf} From The Iclassfactory Failed Due To The Following Error
- The web application [/struts2_0100] created a ThreadLocal with key of type
- The .NET Framework's New SynchronizationContext Class