【发布时间】:2010-06-09 00:03:19
【问题描述】:
这是一个关于在 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();
}
...
这种方法合法吗?我也很好奇这样做更好还是使用 Hardcoded ... 提到的 AtomicReference 方法更好? - 我在 PayloadService 上保留一个 PayloadHolder 实例只是为了在 PayloadService 运行期间保持对 PayloadHolder 类的引用在 jvm 中处于活动状态。
【问题讨论】:
标签: java multithreading synchronization