单例模式

单例模式

单例模式分为了饿汉式和懒汉式,总体来说懒汉式要优于饿汉式,饿汉式不管是否其他线程调用了getInstance,都在类加载阶段创建了实例。而懒汉式则只有在调用的时候,才实例化对象,更加节省系统资源。

饿汉式:

1
2
3
4
5
6
7
8
public class Singleton  {
private static final Singleton INSTANCE = new Singleton();
private Singleton(){}

public static Singleton getInstance() {
return INSTANCE;
}
}

懒汉式-双重检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 懒汉式-双重检查
*/
public class SingletonLazy {
private static SingletonLazy instance = null;

private SingletonLazy() {
}

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

懒汉式-内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 懒汉式-内部类
*/
public class SingletonLazy1 {


private SingletonLazy1() {
}

private static class InnerSingleton {
private final static SingletonLazy1 instance = new SingletonLazy1();
}


public static SingletonLazy1 getInstance() {

return InnerSingleton.instance;
}

public static void helloworld() {
System.out.println("hello lazy singleton.");
}
}

执行Main方法测试,从输出结果看,只有执行了SingletonLazy1.getInstance()方法,才开始加载内部类SingletonLazy1$InnerSingleton。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Main {
public static void main(String[] args) throws InterruptedException{
SingletonLazy1.helloworld();
Object lock = new Object();
synchronized (lock) {
lock.wait(1000);
}
System.out.println("分割线---------------");
System.out.println(SingletonLazy1.getInstance());
}
}

输出结果:
[Loaded sun.nio.cs.US_ASCII$Decoder from /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre/lib/rt.jar]
分割线---------------
[Loaded sun.misc.VMSupport from /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded com.wsy.learn.designmodel.SingletonLazy1$InnerSingleton from file:/Users/wangsiyuan1/workspace/springtest/target/classes/]
com.wsy.learn.designmodel.SingletonLazy1@27716f4

评论