dotgnu-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[DotGNU]Monitor weirdness


From: Thong (Tum) Nguyen
Subject: [DotGNU]Monitor weirdness
Date: Wed, 5 May 2004 17:49:46 +1200

Russell just sent me some test cases which got me thinking about a weird
situation where it appears that you can get two synchronization blocks to
run simultaneously.

Check this code out:

using System;
using System.Threading;

public class Test
{
        Thread thread1, thread2;
        
        public void Run1()
        {
                Thread.Sleep(1000);
                
                lock (this)
                {
                        Monitor.Pulse(this);
                        thread2.Interrupt();
                        
                        for (;;)
                        {
                                Console.WriteLine("Thread 1");
                        }
                }
        }
        
        public void Run2()
        {
                lock (this)
                {
                        try
                        {
                                Monitor.Wait(this);
                        }
                        catch (ThreadInterruptedException)
                        {
                                Console.WriteLine("2 Interrupted");
                        }
                        
                        for (;;)
                        {
                                Console.WriteLine("Thread 2");
                        }
                }
        }

        public void Go()
        {
                thread1 = new Thread(new ThreadStart(Run1));
                thread2 = new Thread(new ThreadStart(Run2));
                
                thread1.Start();
                thread2.Start();
        }
                
        public static void Main()
        {
                new Test().Go();
        }
}


On MS.NET you get a "Thread 1" and "Thread 2" printing out (alternating)
which makes it looks like both synchronization blocks are running at once
(which they are!).  Ouch.

If you modify the code so that Thread 2 tries to Pulse this after it is
interrupted then it will get an exception (indicating it really doesn't own
the lock).  However, thread 2 doesn't get an exception when it exits the
lock block (i.e. when it calls Monitor.Exit).  It shouldn't be able to do
that!  It seems to indicate the VM associates the locking depth for each
monitor with each thread that locks the monitor -- rather than with only
with the current owner (since there can only be one owner).

I guess each monitor could have a linked-list of aborted or interrupted
threads and their depth at interruption.  This would allow Monitor.Exit to
be rewritten to allow interrupted/aborted threads to properly call Exit even
though they don't own the monitor.  From the behaviour of the above program
it looks like this might be what Microsoft does.

Any ideas or suggestions would be helpful.  I'm sleep depraved and now very
confused :-\.  I haven't come across any anything about this problem with
monitors before (in java or .net)!

^Tum



reply via email to

[Prev in Thread] Current Thread [Next in Thread]