民谣- 我有一个帮助器类,其任务是根据参数构建一些消息。该类本身没有任何私有数据(课程实例除外)。
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;
}
}
我知道单例类不是多线程友好的。在这种情况下,当两个线程尝试同时执行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;
}
}
我将保留原始代码,因为它仍然有效,并且为注释和对该问题的答案提供了上下文。
答案 0 :(得分:0)
在这种情况下,不要太多,因为您的构造函数为空(其他人称为没有共享状态)。当您有多个必须初始化的私有实例变量时,问题就开始了。在这种情况下,您需要一些保护,例如doble-check:
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()
代码位于方法内部,如果该方法本身创建了自己的实例或与线程安全类一起使用,则不会有任何问题。