2013-09-22 5 views
0

У меня есть ряд потоков; некоторые из них делят объект; другие разделяют друг друга, в то время как эти объекты находятся в списке (Словарь), разделяемом всеми потоками.Блокировка только одного элемента списка. Правильно ли это?

Другими словами, существует список объектов, которые разделяются всеми потоками, хотя каждый из них использует только один объект этого списка.

У меня нет проблем с параллелизмом путем блокировки основного списка таким образом:

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]); 
     } 
    } 
} 

Мой вопрос, могу ли я сделать это таким образом?

Я имею в виду, могу ли я объявить нестатическую переменную в качестве указателя на элемент статического списка элементов, предполагая, что все процессы разделяют определенный элемент, будут обращаться к нему правильно?

ответ

3

Объект внутри коллекции одинаковый для каждого потока, даже если его положение в списке изменяется, поэтому, если вы собираетесь использовать его для изменения свойств этого объекта, все будет в порядке.

Просто имейте в виду, что замок на Collection[0] не означает «запирать первый элемент в коллекции», но «замок на объекте в настоящее время на первой позиции в коллекции».

+0

Perfect. Спасибо C.Evenhuis !! –

Смежные вопросы