对象锁定不适用于Thread Safety

Tar*_*rik 1 c# thread-safety

我正在测试线程安全性以便更好地掌握,这就是我所做的:

我有一个类型调用ThreadSample,它有两个方法,这里发生锁定:

internal class ThreadTime
    {

        public void doSomething(string message)
        {
            lock (this)
            {
                DialogResult t = MessageBox.Show(message);
                Thread.Sleep(2000);
            }
        }

        public void anotherLife(string message)
        {
            MessageBox.Show("This is coming from anotherLife method and and current threadNumber is " + message);
        }
    }
Run Code Online (Sandbox Code Playgroud)

基本上这个想法是在doSomething()调用时,它应该锁定整个对象,而其他线程甚至可以调用anotherLife方法,因为它们正在等待其他线程释放锁.

这是模拟锁定释放的逻辑:

public partial class Form1 : Form
{
    private ThreadTime time;
    private Thread thread;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        thread = new Thread(new ThreadStart(workerThread));
        time = new ThreadTime();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        thread.Start();
        //Thread.Sleep(1000);
        time.anotherLife("Current thread is = " + "UI Thread");  
    }

    private void workerThread()
    {
        //time.doSomething("Current thread is = " + Thread.CurrentThread.ManagedThreadId);
        time.doSomething("Worker Thread");
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您在下面的代码中看到的那样:

Form被初始化时,一个新的ThreadThreadSample正在创建的.然后,当用户单击时button1,启动线程并且UIThread正在到达并且首先调用anotherLife哪个不是线程安全的.

无论如何,输出是:

  • 有两个MessageBox同时显示.

我期待的是当新线程调用时doSomething(),它获取对象UIThread的锁定并等待释放锁定以便能够调用anotherLife方法.

有人可以解释为什么吗?

谢谢.

Kir*_*oll 5

我期待的是当新线程调用doSomething()时,它获取对象的锁定,UIThread等待释放锁定以便能够调用anotherLife方法.

在允许anotherLife继续之前,UIThread不会等待锁被释放,因为anotherLife没有执行锁定.两个线程都必须运行一个lock语句(锁定在同一个对象上)才能获得您正在寻找的行为.尝试将其修改为:

public void anotherLife(string message)
{
    lock (this) 
    {
        MessageBox.Show("This is coming from anotherLife method and and current threadNumber is " + message);
    }
}
Run Code Online (Sandbox Code Playgroud)