【发布时间】:2021-12-30 19:09:38
【问题描述】:
我正在尝试一些疯狂的事情:p
创建了一个TestClass(遵循单例设计模式) 一个 main 方法,它为 TestClass 初始化反射并启动两个使用反射创建 TestClass 新实例的线程。
下面是代码
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class SingletonPattern {
public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
final TestClass[] i1 = {null};
final TestClass[] i2 = {null};
final Constructor<TestClass> constructor = TestClass.class.getDeclaredConstructor();
constructor.setAccessible(true);
Thread t3 = new Thread() {
@Override
public void run() {
try {
i1[0] = constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread t4 = new Thread() {
@Override
public void run() {
try {
i2[0] = constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t3.start();
t4.start();
t3.join();
t4.join();
System.out.println((i1[0] == i2[0]) + " " + i2[0].equals(i1[0]));
}
static class TestClass implements Cloneable, Serializable{
private static TestClass instance;
private static final Object obj = new Object();
private TestClass() {
synchronized (TestClass.class) {
for (int i = 0; i < 100000; i++) ;
if (instance != null) {
throw new RuntimeException("Operation not allowed. Use getInstance method.");
}
}
}
public static TestClass getInstance() {
if (instance == null) {
synchronized (TestClass.class) {
if (instance == null) {
for (int i = 0; i < 100000; i++) ;
instance = new TestClass();
}
}
}
return instance;
}
public static TestClass getClone() {
try {
return (TestClass) instance.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return instance;
}
private Object readResolve() {
return getInstance();
}
}
}
我得到的输出
false false
如果构造函数中的同步块真的同步了,那么我应该会看到一些异常。但这并没有发生。
谁能解释为什么会这样? 我使用的是 Java 版本:corretto-1.8.0_282
【问题讨论】:
-
只有在
instance不为空时才会引发异常,但据我所知,您没有将instance设置为任一线程中的任何内容。为什么您期望看到异常?你能一步一步地描述它吗?
标签: java multithreading singleton synchronized