【问题标题】:how to make Thread safety and not thread safety如何使线程安全而不是线程安全
【发布时间】:2017-08-19 07:12:04
【问题描述】:

我有这段代码,我想知道它是否是线程安全的!

如果它是线程安全的,如何使它不安全,反之亦然

namespace ThreadSafeTest
{
class Program
{
    static void Main(string[] args)
    {

        Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 1000; i++)
            {
                var user = new User() { Id = i };
                method(user);
            }
        });

        Task.Factory.StartNew(() =>
        {
            for (int i = 1000; i < 2000; i++)
            {
                var user = new User() { Id = i };
                method(user);
            }
        });


        Console.ReadLine();
    }
    static void method( User user)
    {
        Console.WriteLine($@"the {user.Id} is {user.Id}{user.Id}");
    }
}

public class User
{
    public int Id  { get; set; }
}
}

理解这个概念很复杂 谢谢

【问题讨论】:

    标签: c# multithreading static thread-safety


    【解决方案1】:

    您的代码是线程安全的,因为没有共享状态(即不同的线程不共享同一个对象)。唯一的“共享”是对Console.WriteLine 的调用,即thread-safe

    作为如何使其不是线程安全的示例,更改:

    static void method( User user)
    {
        Console.WriteLine($@"the {user.Id} is {user.Id}{user.Id}");
    }
    

    到:

    private static List<User> list = new List<User>();
    static void method( User user)
    {
        list.Add(user);
        Console.WriteLine($@"the {user.Id} is {user.Id}{user.Id}");
    }
    

    因为list.Addnot thread-safe

    请注意,上述 list.Add 代码可能仍然有时工作 - 但它不是保证工作(它会肯定 strong> 如果你运行足够长的时间就会失败)。

    【讨论】:

    • ok list.add 不是线程安全的,但该方法仍然是线程安全的。 bcs 用户 ID 字段从 user 获取其值。我的问题是如何使这种方法不安全?我在某处用 ref 阅读它会不安全,但我不确定
    • method 在我展示的版本中不是线程安全的。如果list.Add 不是线程安全的,而method 调用它,那么(根据定义)method 也不是线程安全的。
    • Somewhere I read with ref it would be unsafe but I'm not sure 你在哪里读到的?
    • 您的代码没有遇到这个问题,因为 a) 您没有使用 ref b) 您没有两个线程访问同一个共享对象。
    猜你喜欢
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 2021-07-12
    • 2011-03-30
    • 1970-01-01
    相关资源
    最近更新 更多