線程同步作業(一):Lock,monitor

 

     開發的系統有這樣一個功能:產生單據號碼。我的做法是查看數據表中單據號碼欄位當前值,在此基礎上加1生成新的單據號碼並存儲。原本沒有想太多,但是我們老大看了後,跟我說,如果有兩個用戶同時訪問到這個單據號碼,那麼新產生的號碼對於數據表來說是重複的,怎麼辦?

     這就涉及一個多用戶訪問共享資源的問題。如果該資源是隻讀的,沒有問題,但是如果每個用戶都可以對其更新操作,就會出現數據同步的問題。說到這裏,想起來,上學的時候學習數據庫就學過的銀行取款的問題,記得當時的解決方案是加鎖,當然今天要解決這個問題依然是加鎖。

     如果究其原因,可以知道,實際上這裏涉及的是一個線程同步的問題(多用戶實際上對服務器來說就是多線程的訪問),msdn中對線程同步的講述和解決方案解釋的很詳細。系統中關於共享訪問資源(數據)的代碼爲關鍵代碼,如果要實現同步,必須在一個線程訪問的時候,對這段代碼加鎖控制。等這個線程訪問完畢,釋放鎖,允許第二個線程的訪問,以此類推

     方案有很多,今天先闡述經常用到的:monitor, lock關鍵字

     測試代碼:

None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Threading;
None.gif
None.gif
namespace Demo1
ExpandedBlockStart.gif
{
InBlock.gif    
class safeThread
ExpandedSubBlockStart.gif    
{
InBlock.gif        
private static object obj=new object();  //注意:這裏設置的對象,最好是private,protected,不能public,否則容易出現問題
InBlock.gif
InBlock.gif        
static void Main()
ExpandedSubBlockStart.gif        
{
InBlock.gif            Thread thread 
= new Thread(new ThreadStart(foo));
InBlock.gif            thread.Name 
= "my thread";
InBlock.gif            thread.Start();
InBlock.gif
InBlock.gif            Thread thread2 
= new Thread(new ThreadStart(foo));
InBlock.gif            thread2.Name 
= "my thread 2";
InBlock.gif            thread2.Start();
InBlock.gif
InBlock.gif            Thread thread3 
= new Thread(new ThreadStart(foo));
InBlock.gif            thread3.Name 
= "my thread 3";
InBlock.gif            thread3.Start();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static void foo()
ExpandedSubBlockStart.gif        
{
InBlock.gif            
InBlock.gif            Monitor.Enter(obj);
ExpandedSubBlockStart.gif            
{
InBlock.gif                Console.WriteLine(Thread.CurrentThread.Name);
InBlock.gif
InBlock.gif                Console.WriteLine(
"Thead executinged");
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            Monitor.Exit(obj); 
//測試的時候把此句註釋掉,即可看到lock的效果
ExpandedSubBlockEnd.gif
        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
      其中Moniter包含的部分及時運行時我們要加鎖的部分,在這裏代碼實現對數據(資源)的訪問和更新。Lock關鍵字的使用更加便捷
None.gif private static void foo()
ExpandedBlockStart.gif        
{   
InBlock.gif           
lock(obj);
ExpandedSubBlockStart.gif            
{
InBlock.gif               
//關鍵代碼區域
InBlock.gif
                Console.WriteLine(Thread.CurrentThread.Name);
InBlock.gif
InBlock.gif                Console.WriteLine(
"Thead executinged");
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }
     實際上,上述兩種方式時等價的(msdn的說法)。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章