Хотя большая часть обсуждения была сосредоточена на синхронизации, я не думал, что они действительно обсуждали разницу. Итак, давайте посмотрим, как синхронизируются блоки и методы.
public synchronized method( Param param ) {
// do some work in here
}
public method( Param param ) {
synchronized( this ) {
// do some work here
}
}
Эти два метода абсолютно одинаковы. Обратите внимание, что нет кода выше или ниже синхронизированного блока. Если бы они были некоторым кодом вне блока, этот код был бы выполнен многопоточностью. Еще одно различие между ними заключается в том, что вы можете изменить код, который выполняется без блокировки, и код, который работает под блокировкой. Это может быть использовано для повышения производительности, если только небольшая часть должна работать под блокировкой, а основная часть метода может выполнять многопоточное повышение производительности, если эта часть является горячей точкой. Теперь давайте посмотрим, как блоки могут предложить большую степень детализации синхронизации, чем методы.
public synchronized method1( Param param ) {
// do something unrelated to method 2
}
public synchronized method2( Param param ) {
// do something unrelated to method 1
}
В этом случае method1 AND method2 будет разрешать поток только в одном из них одновременно, потому что синхронизированные методы блокируют это. Конечно, если бы мы синхронизировали это в блоке, это было бы то же самое. Тем не менее, мы не должны синхронизироваться на этом всегда. Вот способ сделать независимой блокировку method1 и method2.
Object method1Lock = new Object();
Object method2Lock = new Object();
public method1( Param param ) {
synchronized( method1Lock ) {
// do stuff
}
}
public method2( Param param ) {
synchronized( method2Lock ) {
// do stuff
}
}
Это важное различие, потому что теперь method1 и method2 могут выполняться одновременно, когда использование синхронизированных методов не позволит этого. Вы должны помнить, что method1 и method2 ДОЛЖНЫ быть независимыми в своем коде. Если method1 изменяет переменную экземпляра, а method2 считывает эту переменную, они не являются независимыми, и вы должны использовать синхронизацию метода. Однако, если method1 обращается к отдельным переменным экземпляра, чем method2, тогда этот метод может быть использован. Что это все значит? Ни одна техника не превосходит другую. Синхронизация методов проста и понятна, но может иметь более низкую производительность, потому что она слишком сильно блокируется. Блочная синхронизация решает эту проблему, но она более сложная.
Синхронизация важна. Есть проблемы, с которыми невозможно справиться. Тем не менее, лучше быть осторожным и очень стараться не использовать его, когда это не нужно. Есть несколько замечательных методов, которые устраняют блокировку и могут улучшить пропускную способность, поэтому вам также необходимо знать, когда их использовать. Это все просто требует опыта и мудрости. Удачи.