我正在嘗試一些瘋狂的事情:p
創建了一個 TestClass(遵循單例設計模式)一個主要方法,它初始化 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
uj5u.com熱心網友回復:
如果建構式中的同步塊真的同步了,那么我應該會看到一些例外。但這并沒有發生。
在您的 constructor方法中, instance != null將始終回傳 false,因為instace從未分配過。
可以添加instance = this,在這種情況下,只有一個執行緒可以通過反射構造實體,其他執行緒會得到例外:
private TestClass() {
synchronized (TestClass.class) {
for (int i = 0; i < 100000; i ) ;
if (instance != null) {
throw new RuntimeException("Operation not allowed. Use getInstance method.");
}
instance = this;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/361198.html
