Error Monitor.PulaseAll

What is wrong with this example, it throws the error "The object synchronization method was called from an unsynchronized code block" in Monitor.PulaseAll (yyy)?

class Program { static object yyy = 1; public static void test(int x) { while (true) { lock (yyy) { Console.WriteLine("T" + x.ToString()); while (x != (int)yyy) { Monitor.Wait(yyy); continue; } Console.Write(new string(x.ToString()[0], 20)); yyy = 1 + (int)yyy; yyy = ((int)yyy == 4) ? 1 : yyy; Console.WriteLine("------------------------1--"); Monitor.PulseAll(yyy); Console.WriteLine("------------------------2--"); } } } public static void Main () { Thread t1 = new Thread(new ThreadStart(() => { test(3);})); Thread t2 = new Thread(new ThreadStart(() => { test(2);})); Thread t3 = new Thread(new ThreadStart(() => { test(1);})); t1.Start(); t2.Start(); t3.Start(); while (true) Thread.Sleep(500); } } 
+4
source share
1 answer

The error here is changing the lock object .

In Pulse [All] you must have a lock. It looks like you have a lock, but if you look closely, rewrite yyy in code, so this is a different object.

For this reason, lock objects are usually readonly fields.

Also, blocking by type or boxed type is generally a bad idea; the most suitable locking object is:

 private readonly object syncLock = new object(); 

(may be static if necessary)

As a private instance, you avoid unexpected lock conflicts; beig readonly avoids accidental reassignment.

+6
source

All Articles