簡體   English   中英

C#線程安全問題

[英]C# Thread Safety Question

如何使類似該線程的代碼安全?

public static class Converter
{
    public static string ConvertNameToNickname(string name)
    {
        if (name.Equals("John"))
        {
            return "Johnathon";
        }

        return name;
    }
}

還是因為“名稱”是局部變量,它已經是線程安全的了嗎? 我只是想確保是否兩個不同的線程調用了ConvertNameToNickname,它正在評估的名稱不會被其他線程踩到。

<-編輯->

好的,其中一些答案很有幫助,但我仍然沒有找出想要的答案,因此讓我對其進行一些修改並提出相同的問題。 給定可變類型的參數,我如何使此代碼線程安全? 甚至有可能嗎? 如果我在整個方法主體周圍拋出了一個lock {}(如示例2所示),在進入lock語句塊之前,是否仍可以修改實例變量“ name”?

public static class Converter
{
    public static string ConvertNameToNickname(StringBuilder name)
    {
        if (name.ToString().Equals("John"))
        {
            return "Johnathon";
        }

        return name;
    }
}

范例2:

private static readonly object _lockObject = new object();

public static class Converter
{
    public static string ConvertNameToNickname(StringBuilder name)
    {
        lock(_lockObject)
        {
            if (name.ToString().Equals("John"))
            {
                return "Johnathon";
            }

            return name;
        }
    }
}

還是因為“名稱”是局部變量,它已經是線程安全的了嗎?

關。 它是線程安全的,但不是因為局部變量。 但是,由於.NET中的string是不可變的,因此這是線程安全的。 保持線程安全而不同步的關鍵始終在於不可變類型。 對於可變類型,即使.Equals類的方法也可能不是線程安全的。

如果字符串是可變類,則不一定是線程安全的。


編輯:

好的,其中一些答案很有幫助,但我仍然沒有找出想要的答案,因此讓我對其進行一些修改並提出相同的問題。 給定可變類型的參數,我如何使此代碼線程安全? 甚至有可能嗎?

是的,有可能。 但是,它要求某種形式的同步才能正確。 使用鎖是一種選擇。

如果我在整個方法主體周圍拋出了一個lock {}(如示例2所示),在進入lock語句塊之前,是否仍可以修改實例變量“ name”?

不幸的是。 鎖防止從兩個不同的線程模擬調用此代碼 本質上,您正在使對“名稱”線程的這種特定使用安全。 但是,如果在程序的其他位置使用了“名稱”,則仍然有可能在鎖中使用該名稱時通過其他功能對其進行修改。 這可能導致微妙的比賽條件。

線程安全性很難正確實現。 可變類型的線程安全使用的最佳選擇通常是提供您自己的線程安全類型-類型本身在內部處理其所有必需的同步,而公共API完全是線程安全的。 這是確保即使有人在限制使用情況的情況下,也沒有其他人會“干擾”您數據的唯一方法。

這是不可變類型起作用的地方-它們消除了所有這些煩惱,因為一旦創建便無法更改其狀態。 任何人都可以使用它們,並構造更多內容,而不必擔心類型本身。

是的,它已經是線程安全的,因為“名稱”是分配給不可變對象的局部變量。

局部參數是按值傳遞的,因此始終會復制值/引用,而不是ref參數,在這種情況下,如果它是對字段的引用,則可能會出現並發問題。

暫無
暫無

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

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