【问题标题】:Locking just one element of a list. Is this the right way?仅锁定列表的一个元素。这是正确的方法吗?
【发布时间】:2013-09-22 19:31:24
【问题描述】:

我有很多线程;其中一些共享一个对象;其他人共享另一个,而这些对象在所有线程共享的列表(字典)中。

换句话说,有一个对象列表,由所有线程共享,尽管每个线程只使用这个列表中的一个对象。

通过以这种方式锁定主列表,我没有遇到并发问题:

public class MainClass
{
    private static List_of_objects list_of_objects;

    private static object var = new object();

    private static bool list_is_being_used = false;

    public void Main()
    {
        lock (var)
        {
            while(list_is_being_used)
            {
                Monitor.Wait(var);
            }

            list_is_being_used = true;

            // ... Do some things with an object of the list ...

            list_is_being_used = false;

            Monitor.Pulse(var);
        }
    }
}

由于每个线程将只使用列表中的一个元素,我想单独锁定该元素,因此只有使用该元素的线程会被锁定,而使用其他元素的其余线程不会。

我认为这样的事情可以做到:

public class MainClass
{
    private static List_of_objects list_of_objects;

    private static object var_x[] = new object [CONSTANT];  // I declare a mutex-variable for each element on the shared list
    ...

    private static bool element_x_is_being_used[] = [false,false,false,...];

    private ElementClass element; // I declare an object as a pointer to the element this thread is going to use. <---

    public void Main()
    {
        element = list_of_objects[1];

        ...

        lock (object var_x[1]) // I just want to lock this element of the list, not the whole list
        {
            while(element_1_is_being_used)
            {
                Monitor.Wait(object var_x[1]);
            }

            element_1_is_being_used = true;

            // ... Do some things with element 1 of the list ...

            element.set_whatever... // I change some values of the element

            element_1_is_being_used = false;

            Monitor.Pulse(object var_x[1]);
        }
    }
}

我的问题是,我可以这样做吗?

我的意思是,我可以将非静态变量声明为指向静态元素列表中的一个元素的指针,假设所有共享特定元素的进程都可以正确访问它吗?

【问题讨论】:

    标签: c# c#-4.0 concurrency locking mutex


    【解决方案1】:

    集合中的对象对于每个线程都是相同的,即使它在列表中的位置发生变化,所以如果你打算只用它来改变那个对象的属性,你会没事的。

    请记住,锁定Collection[0] 并不意味着“锁定集合中的第一个元素”,而是“锁定对象当前在集合中的第一个位置”。

    【讨论】:

    • 完美。谢谢 C.Evenhuis!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多