iT邦幫忙

0

有關於 C# lock 述句的疑問

小弟剛接觸 C#以及執行緒
現在遇到一個問題是,如果在一個程序內使用lock(),程序會卡死

按照書上的案例,應該會印出
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz才對

可是使用了lock()後卻啥都沒有,貌似卡死了一般
但如果不使用lock則會印出上面那串整齊的數據
不知道是我哪邊理解錯了嗎?
代碼如下

using System;
using System.Threading;

namespace Test_0026_Multithread
{
    class Program
    {
        static void Main(string[] args)
        {
            Program t1 = new Program();
            Thread t2 = new Thread(new ThreadStart(t1.Go));

            t2.Start();
            t1.Go();
        }

        public void Go()
        {
            lock (this)     //此時鎖定以下程序不可被此執行緒以外的程序使用,但實測後,有lock似乎會卡死
            {
                for (char c = 'a'; c <= 'z'; c++)
                {
                    Console.Write(c);
                }
                Console.WriteLine();
            }
        }
    }
}
kgame iT邦新手 4 級 ‧ 2020-03-30 09:57:04 檢舉
我用.NET Core 3.1測試你的程式都沒有死結,正常印出兩行

1 個回答

0
小魚
iT邦大師 1 級 ‧ 2020-03-27 16:55:42

我沒用過this來lock,
通常會用一個無意義的物件,
或是你要鎖定某個物件不在其他地方使用,
也可以lock那個物件.

using System;
using System.Threading;

namespace Test_0026_Multithread
{
    class Program
    {
        object _obj = new object();
        
        static void Main(string[] args)
        {
            Program t1 = new Program();
            Thread t2 = new Thread(new ThreadStart(t1.Go));

            t2.Start();
            t1.Go();
        }

        public void Go()
        {
            lock (_obj)     //此時鎖定以下程序不可被此執行緒以外的程序使用,但實測後,有lock似乎會卡死
            {
                for (char c = 'a'; c <= 'z'; c++)
                {
                    Console.Write(c);
                }
                Console.WriteLine();
            }
        }
    }
}

這樣子試試看可不可以,
我沒有實際跑過.

看更多先前的回應...收起先前的回應...
lazywayne iT邦新手 5 級 ‧ 2020-03-27 17:02:39 檢舉

可以了,不過鎖定一個無意義的物件是指...
這兩個執行去會比較禮貌地互相禮讓這個物件對吧?
然後執行緒1用完之後,執行緒2才可使用...嗎?

可是請問為甚麼如果鎖定的是This會卡死呢??

Program類別實例(就是this)跟Thread(外部程式,他怎麼操作Program類別的實例,你不知道)可能會競爭lock,導致死結吧。

C# lock document

備註
當您同步處理執行緒對共用資源的存取時,請鎖定專用物件執行個體 (例如 private readonly object balanceLock = new object();) 或另一個不太可能由程式碼不相關的部分用作鎖定物件的執行個體。 避免對不同的共用資源使用相同的鎖定物件執行個體,因為其可能導致鎖死或鎖定爭用。 尤其要避免使用下列項目當作鎖定物件:
this,呼叫者可能會將其作為鎖定。
Type 執行個體,因為這些可能會由 typeof 運算子或反映取得。
字串執行個體 (包括字串常值),因為那些可能會暫留。

小魚 iT邦大師 1 級 ‧ 2020-03-29 08:36:38 檢舉

無意義的物件就是指你用不到的物件,
也可以鎖定一個你想鎖定的物件,
讓他在執行這段程式的過程中不會去改到這個物件.

我要發表回答

立即登入回答