簡體   English   中英

無法找出C#中的多線程問題

[英]Can not figure out multithreading trouble in c#

我在多線程方面的第一次經驗有問題。 我想了解它是如何工作的,因此我以我編寫的簡單示例進行了嘗試。

因此,有PaySystem類:

    internal abstract class PaySystem
{
    public int payOperationTime;
    public readonly object _payLock = new object();

    public void Pay()
    {
        Console.WriteLine("There is a pay order in {0} pay system", GetType().Name);

        if (Monitor.TryEnter(_payLock))
        {
            Console.WriteLine("{0} pay system is ready work, so we can start pay operation", GetType().Name);
        }
        else
        {
            Console.WriteLine("{0} pay system is locked now by other pay operation, so we need to wait for end of last", GetType().Name);
        }

        lock (_payLock)
        {
            Console.WriteLine("Start pay operation on {0} pay sytem", GetType().Name);
            Console.WriteLine("payOperationTime for {0} paySystem will be {1}", GetType().Name, payOperationTime.ToString());
            Thread.Sleep(payOperationTime);
        }

        Console.WriteLine("Pay done by {0} pay system", GetType().Name);

    }
}

因此,在我的Main()方法中發生以下操作:

        PayPal payPal = new PayPal();

        Thread payPalPayment = new Thread(payPal.Pay);
        Thread payPalPayment2 = new Thread(payPal.Pay);

        payPalPayment.Start();
        payPalPayment2.Start();

        Console.ReadKey(true);

作為輸出,我得到了不可預測的結果(就我而言)。 我將控制台輸出的打印屏幕附加為文件。

在此處輸入圖片說明

但是,用幾句話來說,它看起來像第二個線程在第一個線程結束它之后繼續付款。

如果我理解正確,我可以啟動線程,並在解鎖儲物櫃時執行/到達被儲物櫃鎖定的塊。

有人可以用正確的方式向我解釋我不了解或不了解的內容嗎?

編輯1

我的問題是:為什么第二線程不繼續付款? 鎖定代碼塊中的行。

編輯2.答案

我想檢查更衣室對象是否被鎖定,並且我使用了TryEnter()方法。 正如我在您的幫助下找到的,親愛的stackoverflow讀者,出於我的目的,我需要使用IsEntered()方法。

謝謝你們。

您似乎對Monitor.Enter和Lock感到困惑。

Monitor.TryEnter嘗試獲取對象上的鎖。 如果成功,則對象將保持鎖定狀態,直到您對其執行Monitor.Exit。 你永遠不會做。

鎖定是Monitor..Enter的縮寫,后跟Monitor.Exit(在代碼塊的末尾)。 鎖定僅是您真正需要的-如果您帶上Monitor.TryEnter,它將按預期工作。

您獲得了兩次鎖,並且僅釋放了一次,因此您仍然持有該鎖。 如果對TryEnter的調用成功,則它所獲取的鎖將永遠不會釋放,從而阻止了另一個線程前進。

使用Monitor.TryEnter + Monitor.Exit或僅使用Lock

Lock語句鎖定並釋放資源。 Monitor.TryEnter僅鎖定。

為了檢查對象是否被鎖定,需要使用Monitor.IsEntered()方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM