写一个单例,无论什么情况下都可能保证只有一个

2020-09-21

方式一:双重检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package app;

/**
* @author devilu
*/
public class Single{

private static volatile Single instance;

private Single() throws Exception {
// 如果用反射的方式new,直接抛异常
if(instance != null){
throw new Exception(getClass()+"already instance");
}
};

public static Single getInstance() throws Exception {
// 提高性能,不要一上来就加锁。
if(instance == null){
// 这里加锁其实就是因为 Volatile 不具备原子性
synchronized (Single.class){
if (instance == null){
instance = new Single();
}
}
}
return instance;
}

}

方式二:静态代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package app;

public class SingleStatic {

private static SingleStatic singleStatic;

static {
singleStatic = new SingleStatic();
}

private SingleStatic(){
if(singleStatic != null){
throw new RuntimeException(getClass()+" already instance");
}
}

public static SingleStatic getInstance(){
return singleStatic;
}

}

方式一测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) throws Exception {


Single single = Single.getInstance();
Single single1 = Single.getInstance();
Single single2 = Single.getInstance();

System.out.println(single);
System.out.println(single1);
System.out.println(single2);
System.out.println("--------");


Class<Single> singleClass = (Class<Single>) Class.forName("app.Single");
Constructor<Single> declaredConstructor = singleClass.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
Single single3 = declaredConstructor.newInstance();
Single single4 = declaredConstructor.newInstance();
System.out.println(single3);
System.out.println(single4);

}

结果:

image-20200921143546030

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章