Mirza
Mirza

Reputation: 199

try/catch when trying to lock object

I'm new to multithreading. I tried to lock object when it is locked by another thread, i expecting an error and try to use Exception but it didn't worked.

class Program
    {
        static readonly object lockNum = new object();
        static int A = 10;

        public static void Thread1()
        {
            lock (lockNum)
            {
                A = 100;
                Console.WriteLine(A);
            }
        }

        public static void Thread2()
        {
            Thread.Sleep(1000);
            lock (lockNum)
            {
                Thread.Sleep(9000);
                Console.WriteLine(A);
                Console.WriteLine("Thread 2 is executed");
            }
        }

        public static void Thread3()
        {
            Thread.Sleep(3000);

            try
            {
                lock (lockNum)
                {
                    Console.WriteLine(A);
                    Console.WriteLine("Thread 3 is executed");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Object is locked");
            }

        }

    }

    public class MyClass
    {

        public static void Main()
        {
            Thread tid1 = new Thread(new ThreadStart(Program.Thread1));
            Thread tid2 = new Thread(new ThreadStart(Program.Thread2));
            Thread tid3 = new Thread(new ThreadStart(Program.Thread3));

            tid1.Start();
            tid2.Start();
            tid3.Start();

            Console.ReadLine();
        }
    }

The Thread2 and Thread3 is run together after the Thread.Sleep(9000); i expecting there is an Exception after 3sec because the object is still locked by Thread2. I was trying to make Thread3 sleep for 3sec again to check if the object is unlocked (maybe WriteLine the error) the and repeat until the object is unlocked.

Upvotes: 1

Views: 1596

Answers (2)

bottaio
bottaio

Reputation: 5093

Your code should look like this:

public static void Thread3()
    {
        Thread.Sleep(3000);

        try
        {
            if (Monitor.TryEnter(lockNum))
            {
                Console.WriteLine(A);
                Console.WriteLine("Thread 3 is executed");
            }
            else throw new Exception();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Object is locked");
        }

    }

EDIT1: Argh... the explanation is provided by the other guy,

EDIT2: Actually this is not the best way to handle it. Exceptions are heavy. You can get rid of try catch block and instead of throwing an exception you can print out your message.

Upvotes: 2

C.Evenhuis
C.Evenhuis

Reputation: 26446

Locks don't throw exceptions, they simply wait until the other thread has released the lock.

If you want to skip code if the lock cannot be claimed, you could use

if (Monitor.TryEnter(lockNum))
{
    Console.WriteLine("No one else had the lock, now it's mine!");
}
else
{
    Console.WriteLine("Another thread won :(");
}

You can optionally provide a timeout to that method.

Upvotes: 3

Related Questions