锁定对象上的访问属性,没有锁定语句

时间:2014-01-15 14:20:59

标签: c# multithreading concurrency locking

说我有以下代码:

public class FooBar
{
    public int Var1{ get; set; }
}

public static void main( string[] args )
{
    var foo = new FooBar();
    //Start new thread ...
    {
        lock( foo )
        {
            foo.Var1 = 1;
            Thread.Sleep( 10000 );
        }
    }

    //Start another thead ...
    {
        Console.WriteLine( foo.Var1 );
    }
}

第二个线程是否能够访问该属性并在另一个线程处于休眠状态并且具有锁定时写入控制台,还是必须等到另一个线程完成休眠并存在?

2 个答案:

答案 0 :(得分:0)

如果有疑问,只需测试一下:

public class FooBar
{
    public int Var1 { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var foo = new FooBar();
        foo.Var1 = 0;
        Thread t = new Thread(new ParameterizedThreadStart(NewThread));
        t.Start(foo);

        lock (foo)
        {
            foo.Var1 = 1;
            Thread.Sleep(10000);
            foo.Var1 = 2;
        }
    }
    public static void NewThread(object foo)
    {
        Thread.Sleep(5000);
        Console.WriteLine((foo as FooBar).Var1);
    }

}

这证明是的,即使另一个线程已将其锁定,它也可以访问它。但是,如果您在读取之前选择在NewThread方法中锁定变量,它将被阻止。

答案 1 :(得分:0)

这可能会对您有所帮助:

class Program
{
    static void Main(string[] args)
    {
        var foo = new FooBar();

        // new thread which tries to change the property foo.Var1
        FooBarChanger changer = new FooBarChanger(ref foo);
        var subThread = new Thread(changer.TryChange);
        subThread.IsBackground = true;
        subThread.Start();

        lock (foo)
        {
            foo.Var1 = 1;
            Console.WriteLine("main - lock: {0}", foo.Var1);
            Thread.Sleep(10000);
            Console.WriteLine("main - lock: updated value: {0}", foo.Var1);
        }

        Console.ReadLine();
    }
}

public class FooBarChanger
{
    private FooBar _b;

    public FooBarChanger(ref FooBar b)
    {
        _b = b;
    }

    public void TryChange()
    {
        Thread.Sleep(1000);
        Console.WriteLine("subthread: changing value now!");
        _b.Var1 = 100;
        Console.WriteLine("subthread: {0}", _b.Var1);
    }
}

public class FooBar
{
    public int Var1 { get; set; }
}

下面的代码能够更改属性的值并创建以下输出:

主锁 - 1 subthread:现在改变价值!
子线程:100
main - lock:更新值:100

希望我能帮到你一点:) 托比