gpt4 book ai didi

Java单例类和多线程

转载 作者:太空宇宙 更新时间:2023-11-04 09:49:41 24 4
gpt4 key购买 nike

各位——我有一个帮助器类,其任务是根据参数构建一些消息。该类本身没有任何私有(private)数据(当然除了实例之外)。

public class RequestBuilder {
private static RequestBuilder instance = new RequestBuilder();

private RequestBuilder() {}

public static RequestBuilder getInstance() {
return instance;
}

public SetRequest buildSetRequest(Path prefix,
Path path,
ConfigEntity configEntity,
Any protoAnyData) {
.....
.....
return setRequest;
}

public GetRequest buildGetRequest(Path prefix,
Path Path,
RetrieveRequestEntity retrieveRequestEntity,
Encoding encoding) {
.....
.....
return getRequest;
}
}

我知道单例类对多线程不友好。在这种情况下,当 2 个线程尝试同时执行 buildSetRequest() 时会发生什么?

感谢您的宝贵时间。

编辑:根据我的需要,并按照 @BoristheSpide 在下面的评论中的建议,我将把此类作为实用程序类,并进行以下更改:1. 确定最终结果。2. 使方法静态化。3. 删除所有单例引用。

public final class RequestBuilder {

private RequestBuilder() {}

public static SetRequest buildSetRequest(Path prefix,
Path path,
ConfigEntity configEntity,
Any protoAnyData) {
.....
.....
return setRequest;
}

public static GetRequest buildGetRequest(Path prefix,
Path Path,
RetrieveRequestEntity retrieveRequestEntity,
Encoding encoding) {
.....
.....
return getRequest;
}
}

我保留原始代码不变,因为它仍然有效,并为该问题的评论和答案提供了上下文。

最佳答案

在这种情况下,不要太多,因为您的构造函数是空的(其他人提到的是没有共享状态)。当您有多个必须初始化的私有(private)实例变量时,问题就会出现。在这种情况下,您需要一些保护,例如双重检查:

private static volatile RequestBuilder instance;

private RequestBuilder() {}

public static RequestBuilder getInstance() {
if (instance == null) {
synchronized (RequestBuilder.class) {
if (instance == null) {
instance = new RequestBuilder();
}
}
}
return instance;
}

原因是线程可以随时被挂起。如果构造实例的当前线程被挂起,并且另一个线程到来,则可能存在半初始化的实例变量,并且该对象最终可能处于损坏状态。

编辑:关于buildSetRequest()

代码位于方法内部,如果该方法本身创建自己的实例或与线程安全类一起使用,则不会有任何问题。

关于Java单例类和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54932779/

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