gpt4 book ai didi

java - 在 Java 中同步共享静态对象的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-03 20:21:19 25 4
gpt4 key购买 nike

这是一个关于在 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 中处于 Activity 状态的引用。

最佳答案

您的代码应如下所示:

public static  void setPayload(PayloadDTO payload){
synchronized(PayloadService.class){
PayloadService.payload = payload;
}
}

public static PayloadDTO getPayload() {
synchronized(PayloadService.class){
return PayloadService.payload ;
}
}

即使方法不是静态的,您的原始代码也不会工作。原因是您正在同步正在更改的负载实例。

更新,对 johnrock 评论的回应:如果您当前有其他要运行的同步静态 block ,则锁定整个类只是一个问题。如果你想拥有多个独立的锁定部分,那么我建议你这样做:

public static final Object myLock = new Object();

public static void setPayload(PayloadDTO payload){
synchronized(myLock){
PayloadService.payload = payload;
}
}

public static PayloadDTO getPayload() {
synchronized(myLock){
return PayloadService.payload ;
}
}

或者,如果您需要更复杂的并发模式,请查看 java.util.concurrent其中有许多预建类可以帮助您。

关于java - 在 Java 中同步共享静态对象的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3002251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com