2016-05-24 1 views
1

я читал на официальном учебнике по многопоточности из oracle и я пришел пересечь этот пример (при условии, c1 и c2 никогда не используются вместе):Использование синхронизированных блоков для различных методов в одном классе

public class MsLunch { 
    private long c1 = 0; 
    private long c2 = 0; 
    private Object lock1 = new Object(); 
    private Object lock2 = new Object(); 

    public void inc1() { 
     synchronized(lock1) { 
      c1++; 
     } 
    } 

    public void inc2() { 
     synchronized(lock2) { 
      c2++; 
     } 
     } 
    } 
} 

Говорят что, используя блокировку 1 & lock 2, это помогает уменьшить ненужную блокировку по сравнению с использованием этого слова в синхронизированном блоке.

Однако я действительно не вижу, как это помогает уменьшить блокировку, поскольку они не имеют зависимости друг от друга. У меня есть несколько потоков, каждый из которых запускает эти два метода одновременно, и производительность довольно похожа, когда я использую объекты блокировки и это ключевое слово.

Может кто-нибудь помочь объяснить мое замешательство здесь? Любовь, чтобы увидеть объяснение с примером, чтобы ясно проиллюстрировать разницу.


Добавление к обсуждению здесь, это post помогли прояснить мои сомнения, а также. Ключевой момент: синхронизация по методу означает, что нить должна получить блокировку экземпляра объекта до ввода этого метода.

+0

Чтобы увидеть разницу в производительности в этом случае, вам придется совершать большое количество вызовов, используя большое количество потоков, вызывающих ваши 2 метода случайным образом и одновременно. Однако, если вызовы делали больше, чем увеличивали переменную, то разница между 1 и 2 замками была бы более очевидной. – Gray

ответ

3

Вы используете два разных замка: один для защиты inc1 и другой для защиты inc2. Это означает, что поток X может запускать inc1, а другой поток работает inc2. Если бы они использовали один и тот же замок (независимо от того, является ли он this или другим объектом блокировки), вы не сможете запускать их одновременно. Таким образом, теоретически, по крайней мере, наличие двух разных блокировок должно повысить вашу производительность в этом сценарии.

+0

Я понимаю вашу точку здесь. Я предполагаю, что моя путаница в том, что если c1 и c2 обновляются в этом случае двумя способами отдельно, то наличие двух разных блокировок влияет на производительность по сравнению с использованием только одной блокировки. Из вашего ответа, я думаю, вы говорите, что синхронизированные блоки с использованием одной и той же блокировки не будут выполняться одновременно - в этом случае c2 не будет обновляться, если c1 обновляется в разных потоках? – hao

+0

@hao точно - вот почему у нас есть блокировки - чтобы один поток не мешал другому, независимо от того, работает ли тот же метод или нет. – Mureinik

+1

Дело в том, что, поскольку вы пытаетесь защитить две независимые переменные, вы можете использовать два независимых замка. Если поток A находится в вызове 'inc1()', это не должно быть причиной для блокирования потока B от ввода 'inc2()'. –

 Смежные вопросы

  • Нет связанных вопросов^_^