简体   繁体   中英

Exception : Object synchronization method was called from an unsynchronized block of code

I have several threads that write to the same int. Each thread increment the integer value. What is the simple way to synchronize the increment operation. The lock statement works only on Object so i can't use it. I tried also the following:

static int number=0;

static void Main(string[] args)
    {
        ThreadStart ts = new ThreadStart(strtThread);
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        Console.ReadLine();
    }

    public static void strtThread()
    {
        bool lockTaken = false;

        Monitor.Enter(number,ref lockTaken);
        try
        {
            Random rd = new Random();
            int ee = rd.Next(1000);
            Console.WriteLine(ee);
            Thread.Sleep(ee);
            number++;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally 
        {
            if (lockTaken)
            {
             Monitor.Exit(number);
            }

        }
    }

It gives me the following error:

Object synchronization method was called from an unsynchronized block of code.

You can use the Interlocked.Increment Method to automically increment an integer without locking:

public static void strtThread()
{
    Interlocked.Increment(ref number);
}

If you have multiple statements, you can create an object instance that you can lock :

private static int number = 0;
private static readonly object gate = new object();

public static void strtThread()
{
    lock (gate)
    {
       number++;
    }    
}

Why would you bother with the number ? I think that's the problem. Try this:

static Object locking = new Object();

static void Main(string[] args)
    {
        ThreadStart ts = new ThreadStart(strtThread);
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        Console.ReadLine();
    }

    public static void strtThread()
    {
        lock(locking) {
            try
            {
                Random rd = new Random();
                int ee = rd.Next(1000);
                Console.WriteLine(ee);
                Thread.Sleep(ee);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

Interlocked.Increment provides an atomic increment. The Interlocked class in general "provides atomic operations for variables that are shared by multiple threads."

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM