Skip to content

Latest commit

 

History

History
76 lines (55 loc) · 2.09 KB

rule.adoc

File metadata and controls

76 lines (55 loc) · 2.09 KB

Locking on a class field synchronizes not on the field itself, but on the object assigned to it. So locking on a non-readonly field makes it possible for the field’s value to change while a thread is in a block locked on the old value. That would allow a second thread, locked on the new value, to enter the block at the same time.

Locking on a readonly field of a class which is not private allows external code to lock the field, potentially interfering with synchronization of methods in that class.

Locking on a local variable or on a new instance undermines the synchronization: two different threads running the same method in parallel would lock on two different object instances. That would allow a second thread, locked on that new value, to enter the same block concurrently.

Locking on a string literal is even more dangerous: depending on whether the string is interned or not, different threads may or may not synchronize on the same object instance.

Noncompliant Code Example

private Color colorObject = new Color("red");
private readonly colorString = "red";

private void DoSomething()
{
  // Synchronizing access via "colorObject"
  lock (colorObject) // Noncompliant; lock is actually on object instance "red" referred to by the color field
  {
    //...
    colorObject = new Color("green"); // other threads now allowed into this block
    // ...
  }
  lock (new object()) // Noncompliant; this is a no-op
  {
    // ...
  }
  lock (colorString)  // Noncompliant; strings can be interned
  {
    // ...
  }
}

Compliant Solution

private Color colorObject = new Color("red");
private readonly object lockObj = new object();

private void DoSomething()
{
  lock (lockObj)
  {
    //...
    color = new Color("green");
    // ...
  }
}

Implementation Specification

(visible only on this page)


(visible only on this page)