Стоимость блокировки в .NET и Java

Я играл с фреймворком Disruptor и его портом для платформы .NET и нашел интересный случай. Может быть, я что-то совсем упустил, поэтому ищу помощи у всемогущего сообщества .

        long iterations = 500*1000*1000;
        long testValue = 1;

        //.NET 4.0. Release build. Mean time - 26 secs;
        object lockObject = new object();
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            lock (lockObject)
            {
                testValue++;    
            }
        }
        sw.Stop();

        //Java 6.25. Default JVM params. Mean time - 17 secs.
        Object lock = new Object();
        long start = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++)
        {
                synchronized (lock)
                {
                    testValue++;
                }
        }
        long stop = System.currentTimeMillis();

Похоже, что получение блокировки в сценарии с помощью единственного потока в .NET стоит всего на 50% дороже, чем в Java . Сначала я с подозрением относился к таймерам, но я несколько раз запускал один и тот же тест с результатами, близкими к упомянутым выше средним значениям. Затем я с подозрением отнесся к блоку кода synchronized , но он делает не больше, чем просто monitorenter / monitorexit инструкции байтового кода - то же самое, что lock ключевое слово в .NET. Есть ли другие идеи, почему взятие блокировки так дорого в .NET и Java?

28
задан duffymo 27 August 2011 в 18:15
поделиться

1 ответ

Java JIT оптимизирует синхронизацию, так как объект блокировки является локальным потоком (то есть он ограничен стеком потока и никогда не используется совместно) и, следовательно, никогда не может быть синхронизирован из другого потока. Я не уверен, что .NET JIT сделает это.

См. эту очень информативную статью , особенно часть, посвященную выбору замка.

0
ответ дан 28 November 2019 в 03:40
поделиться