小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C#線程系列講座(5):同步技術(shù)之Monitor - 哈佛校訓(xùn) - 博客園

 kittywei 2011-05-04
在上一講介紹了使用lock來實現(xiàn)線程之間的同步。實際上,這個lockC#的一個障眼法,在C#編譯器編譯lock語句時,將其編譯成了調(diào)用Monitor類。先看看下面的C#源代碼:
public static void MyLock()
{
    
lock (typeof(Program))
    {
    }
}


   
上面的代碼通過lock語句使MyLock同步,這個方法被編譯成IL后,代碼如圖1所示。



                                                         圖1

    從上圖被標(biāo)注的區(qū)域可以看到,一條lock語句被編譯成了調(diào)用MonitorEnterExit方法。MonitorSystem.Threading命名空間中。lock的功能就相當(dāng)于直接調(diào)用MonitorEntry方法,所不同的是,lock方法在結(jié)束后,會自動解除鎖定,當(dāng)然,在IL中是調(diào)用了MonitorExit方法,但在C#程序中,看起來是自動解鎖的,這類似于C#中的using語句,可以自動釋放數(shù)據(jù)庫等的資源。但如果直接在C#源程序中使用Monitor類,就必須調(diào)用Exit方法來顯式地解除鎖定。如下面的代碼所示:

Monitor.Entry(lockObj);
try
{
    
// lockObj的同布區(qū)
}
catch(Exception e)
{
    
// 異常處理代碼
}
finally
{
    Monitor.Exit(lockObj);  
// 解除鎖定
}


    Exit方法最后在finally里調(diào)用,這樣無論在方法在發(fā)生異常、返回還是正常執(zhí)行,都會執(zhí)行到finally,并調(diào)用Exit方法解除鎖定。

    Monitor類不僅可以完全取代lock語句(如果只使用lock語句本身的功能,最好還是直接用lock語句吧),還可以使用TryEntry方法設(shè)置一個鎖定超時,單位是毫秒。如下面的代碼所示:

if(Monitor.TryEntry(lockObj, 1000))
{
    
try
    {
    }
    
finally
    {
        Monitor.Exit(lockObj);
    }
}
else
{
    
// 超時后的處理代碼
}

 

    上面的代碼設(shè)置了鎖定超時時間為1秒,也就是說,在1秒中后,lockObj還未被解鎖,TryEntry方法就會返回false,如果在1秒之內(nèi),lockObj被解鎖,TryEntry返回true。我們可以使用這種方法來避免死鎖,如下面的代碼所示:

    class Program
    {
        
private static Object objA = new Object();
        
private static Object objB = new Object();
        
public static void LockA()
        {
            
if (Monitor.TryEnter(objA, 1000))
            {
                Thread.Sleep(
1000);
                
if (Monitor.TryEnter(objB, 2000))
                {
                    Monitor.Exit(objB);
                }
                
else
                {

                    Console.WriteLine(
"LockB timeout");
                }
                Monitor.Exit(objA);
            }
            Console.WriteLine(
"LockA");
        }
        
public static void LockB()
        {
            
if (Monitor.TryEnter(objB, 2000))
            {
                Thread.Sleep(
2000);
                
if (Monitor.TryEnter(objA, 1000))
                {
                    Monitor.Exit(objA);
                }
                
else
                {
                    Console.WriteLine(
"LockA timeout");
                }
                Monitor.Exit(objB);
            }
            Console.WriteLine(
"LockB");
        }
        
public static void Main()
        {
            Thread threadA 
= new Thread(LockA);
            Thread threadB 
= new Thread(LockB);
            threadA.Start();
            threadB.Start();
            Thread.Sleep(
4000);         
            Console.WriteLine(
"線程結(jié)束");
        }
    }

 

    上面的代碼是在上一講舉的死鎖的例子,但在這一講將lock語句改成了TryEntry方法,而且設(shè)置了鎖定超時間,由于在等待一定時間后,不管被鎖定的對象是否被解鎖,TryEntry方法都會返回,因此,上面的代碼是不會死鎖的。運(yùn)行上面的代碼的結(jié)果如圖2所示。



                                              圖2

    如果TryEntry方法的超時時間為System.Threading.Timeout.Infinite,TryEntry方法就相當(dāng)于Entry方法,如果超時時間為0,不管是否解鎖,TryEntry方法都會立即返回。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多