Diferença entre o bloqueio (este) e um bloqueio no object estático

Qual dos dois trechos de código a seguir é melhor usar?

static readonly object _locker = new object(); lock (_locker) 

ou

 lock (this) 

this é um object da instância atual. Então, por que o lock (_locker) sempre nos livros?

Relacionado:
Qual é a diferença entre travar (this) e travar (thisLock)?
Por que o lock (this) {…} é ruim?

Pode haver uma grande diferença. A maior diferença entre os dois é que o primeiro exemplo usa um único object para travar (daí a palavra-chave static ), enquanto a palavra this chave this no segundo exemplo implica o bloqueio em uma instância. Portanto, pode haver uma grande diferença do ponto de vista de desempenho e até mesmo de uma perspectiva de correção, mas isso depende do código dentro da fechadura.

Quando tudo o que você precisa é sincronizar o access a campos de nível de instância, você não deve usar a palavra-chave static , pois ela sincronizará o código em si, em vez dos dados (o que pode causar um impacto desnecessário no desempenho). Obviamente, se os dados em si forem estáticos (dados em nível de class, em vez de dados em nível de instância), será necessário usar a palavra-chave static . Por outro lado, quando você usa a palavra-chave this para bloquear, enquanto acessa resources compartilhados / estáticos, você terá (é claro) um problema de correção, já que a synchronization é baseada em instâncias e várias instâncias ainda poderão acessar os dados compartilhados ao mesmo tempo.

E há outro problema, mas a diferença é muito menor do que para as diferenças anteriormente observadas. O primeiro exemplo usa um object declarado de forma privada para bloquear, enquanto o outro usa o ponteiro this , que é a referência ao object desse método de instância. Como essa referência é publicamente acessível a outros objects, é possível que eles a bloqueiem, o que poderia causar travamentos em raras circunstâncias. Se você é um desenvolvedor de aplicativos, eu não me preocuparia muito com isso (contanto que você não bloqueie coisas como System.String ou System.Type ), mas se você for um desenvolvedor de framework, certamente não use lock(this) , já que não há como saber de que maneira os desenvolvedores de aplicativos irão (ab) usar seu código.

Quase sempre é preferível bloquear um object readonly particular.

A diferença é que this geralmente é visível para o código externo, o que pode bloquear isso, ou seja,

 var obj = new YourClass(); lock(obj) { ... } 

YourClass caso, qualquer tentativa dentro de YourClass para lock (this) iria bloquear.

Porque você não quer que o bloqueio seja acessado de fora do object.

Se você usar lock (this), você pode obter um deadlock:

 void blah() { lock(this); sleep(200); } //Some other block of code MyObject a; foreach(Mythread m in threads) { lock(a); m.Call(a.blah); //Not the best syntax, but you get the idea. } 

Se você mantiver a trava dentro do object, isso não trava.