C# 为什么泛型类的实例在一个单独的线程上被修改,而普通类的实例却没有?

C# 为什么泛型类的实例在一个单独的线程上被修改,而普通类的实例却没有?,c#,.net,generics,multithreading,C#,.net,Generics,Multithreading,当在单独线程上运行的方法中更改对象时,调用线程(启动该方法运行的线程的线程)上的对象不会更改。 但是,如果定义该对象的类是泛型的,则该对象在调用线程上会发生更改。例如: 我有两门课: public class Holder<T> { public T Value {get;set;} } 我有第三个名为client的对象,它在方法Change()上将值设置为单独线程上的不同值: static void main(string[] args) { Holder<Stri

当在单独线程上运行的方法中更改对象时,调用线程(启动该方法运行的线程的线程)上的对象不会更改。 但是,如果定义该对象的类是泛型的,则该对象在调用线程上会发生更改。例如:

我有两门课:

public class Holder<T> { public T Value {get;set;} }
我有第三个名为client的对象,它在方法Change()上将值设置为单独线程上的不同值:

static void main(string[] args)
{
    Holder<String> test = new Holder<String>();
    test.Set("original");
    Client client = new client(test);
    client.Change(test);
    Console.WriteLine(test.Value);
    // test.Value now returns "changed"
    // But if test was of type Holder2, it would return "original"
}
static void main(字符串[]args)
{
支架测试=新支架();
测试集(“原件”);
客户端=新客户端(测试);
客户变更(测试);
控制台写入线(测试值);
//test.Value现在返回“changed”
//但若测试类型为Holder2,它将返回“原始”
}
因此,客户机的基本功能是:

public class Client
    {
        Holder<String> test;
        public Client(Holder<String> test)
        {
            this.test = test;
        }
        public void Change()
        {
            ThreadStart ts = new ThreadStart(Alter);
        Thread t = new Thread(ts);
        t.Start();
    }

        public void Alter()
        {
        test.Value = "changed";
    }
    }
公共类客户端
{
保持架试验;
公共客户(持有人测试)
{
这个。测试=测试;
}
公共空间更改()
{
ThreadStart ts=新的ThreadStart(Alter);
螺纹t=新螺纹(ts);
t、 Start();
}
公开作废
{
test.Value=“已更改”;
}
}

但是,如果我将客户机类改为take Holder2,它不是泛型的,它将不再工作。也就是说,test.Value将返回“original”。有人能给我解释一下,为什么会这样吗?

因为你不使用锁定,所以有一个种族条件可以解释你的观察结果


另外:请显示调用客户端后如何显示变量。更改(测试)

由于您不使用锁定,因此存在一种竞争条件,可以解释您的观察结果


另外:请显示调用客户端后如何显示变量。更改(测试)

这个小而完整的程序演示了这个问题(例如什么是
Set
?)这与泛型无关,而是与线程和计时有关。您不必等待
Alter
方法完成。任何可复制性都是偶然的,你是对的。我加入了Thread.Sleep(2000),这给了Alter方法一些时间来完成。塔克斯!这个小而完整的程序演示了这个问题(例如什么是
Set
?)这与泛型无关,而是与线程和计时有关。您不必等待
Alter
方法完成。任何可复制性都是偶然的,你是对的。我加入了Thread.Sleep(2000),这给了Alter方法一些时间来完成。塔克斯!
public class Client
    {
        Holder<String> test;
        public Client(Holder<String> test)
        {
            this.test = test;
        }
        public void Change()
        {
            ThreadStart ts = new ThreadStart(Alter);
        Thread t = new Thread(ts);
        t.Start();
    }

        public void Alter()
        {
        test.Value = "changed";
    }
    }