Это вопрос относительно того, как правильно синхронизировать общий объект в Java.Одно предостережение: доступ к объекту, которым я хочу поделиться, должен осуществляться из статических методов.Мой вопрос: если я синхронизирую на статическом поле, блокирует ли этот класс класс, к которому относится поле, подобно тому, как это делает синхронизированный статический метод?Или это будет блокировать только само поле?
В моем конкретном примере я спрашиваю: вызовет ли PayloadService.getPayload () или PayloadService.setPayload () блокировку PayloadService.payload?Или он заблокирует весь класс PayloadService?
public class PayloadService extends Service {
private static PayloadDTO payload = new PayloadDTO();
public static void setPayload(PayloadDTO payload){
synchronized(PayloadService.payload){
PayloadService.payload = payload;
}
}
public static PayloadDTO getPayload() {
synchronized(PayloadService.payload){
return PayloadService.payload ;
}
}
...
Это правильный / приемлемый подход?
В моем примере PayloadService представляет собой отдельный поток, обновляющий объект полезной нагрузки через регулярные промежутки времени - другие потоки должны вызывать PayloadService.getPayload () через случайные интервалы для получения последних данных, и мне нужно убедиться, что онине блокируйте PayloadService от выполнения своей задачи таймера
На основании полученных ответов я рефакторинг сделал следующее:
public class PayloadHolder {
private static PayloadHolder holder;
private static PayloadDTO payload;
private PayloadHolder(){
}
public static synchronized PayloadHolder getInstance(){
if(holder == null){
holder = new PayloadHolder();
}
return holder;
}
public static synchronized void initPayload(){
PayloadHolder.payload = new PayloadDTO();
}
public static synchronized PayloadDTO getPayload() {
return payload;
}
public static synchronized void setPayload(PayloadDTO p) {
PayloadHolder.payload = p;
}
}
public class PayloadService extends Service {
private static PayloadHolder payloadHolder = PayloadHolder.getInstance();
public static void initPayload(){
PayloadHolder.initPayload();
}
public static void setPayload(PayloadDTO payload){
PayloadHolder.setPayload(payload);
}
public static PayloadDTO getPayload() {
return PayloadHolder.getPayload();
}
...
Законен ли этот подход?Мне также любопытно, лучше ли это делать таким образом или использовать подход AtomicReference, упомянутый Hardcoded ...?- Я держу экземпляр PayloadHolder на PayloadService просто для того, чтобы поддерживать ссылку на класс PayloadHolder активным в jvm до тех пор, пока работает PayloadService.