2010-05-15 4 views
4
public class A { } 
public class B:A { } 

void foo() 
{ 
    A a = new B(); 
    B b = a as B; 
} 

для данной установки, будет lock(a) эквивалентен lock(b)?Является ли замок() безопасным?

Я имею в виду, что блокировка будет взаимоисключающей? Если I lock(a) в одном потоке и lock(b) в другом потоке, я получу взаимно эксклюзивный доступ к этому единственному экземпляру B, созданному ранее?

+0

Что значит точно эквивалент? –

ответ

12

Да lock(a){} равнозначно lock(b){}.

The lock() documentation утверждает, что оператор блокировки отмечает блок оператора как критический раздел путем получения блокировки взаимного исключения для заданного объекта ссылочного типа.

a и b - оба объекта, поэтому да, они эквивалентны. Фактически a и b являются ссылками на один и тот же объект.

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

Быстрая тестовая программа показывает, что она действительно ведет себя так, как это документированный:

namespace ConsoleApplication2 
{ 
    public class A { } 
    public class B : A { } 

    class Program 
    { 
     static A a = new B(); 

     static void MyThread() 
     { 
      B b = a as B; 
      lock (b) 
      { 
       Console.WriteLine("b lock acquired"); 
       Console.WriteLine("releasing b lock"); 
      } 

     } 


     static void Main(string[] args) 
     { 
      System.Threading.Thread t = new System.Threading.Thread(MyThread); 

      lock(a) 
      { 
       Console.WriteLine("a lock acquired");    
       t.Start(); 
       System.Threading.Thread.Sleep(10000); 
       Console.WriteLine("Releasing a lock"); 
      } 
     } 
    } 
} 

замок приобрел
... 10 секунд пройти
снятия блокировки замка
б приобретенную
освобождение b блокировка

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