c# - 对象锁不适用于线程安全

标签 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);
        }
    }

基本上,当 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");
    }
}

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

Form 被初始化时,一个新的 ThreadThreadSample 被创建。然后,当用户点击 button1 时,线程启动,UIThread 到达并调用 anotherLife,这起初不是线程安全的。

无论如何,输出是:

  • 同时显示两个MessageBox。

我所期望的是当新线程调用doSomething()时,它获得了对象的锁并且UIThread等待锁被释放以便能够调用 anotherLife 方法。

谁能解释一下为什么?

谢谢。

最佳答案

What I was expecting is when the new Thread invokes doSomething(), it gets the lock of the object and UIThread waits for the lock to be released to be able to invoke anotherLife method.

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

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

关于c# - 对象锁不适用于线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4401438/

相关文章:

c# - 如何删除 HTML 标签中的所有属性

c# - 嵌套泛型函数的类型推断

c# - WPF 复选框样式更改

c# - 以下 C# 代码线程安全吗?

c# - Telerik MVC Extensions Grid - 如何将网格过滤器应用于初始 LINQ 查询或传递到数据库?

c# - 根据在另一个下拉菜单中选择的值填充下拉菜单/选择

c# - StreamReader ThreadSafe问题?可能吗?

java - Java Spring Bean 中的实例变量

java - Lambda 表达式中的 "Starting new Thread in constructor"警告 (NetBeans IDE)

java - 如果我有两个方法不能在不同线程的一个类中同时发生,如何锁定它?