单例模式

类图

代码

1.懒汉(线程不安全)

1
2
3
4
5
6
7
8
9
10
11
12
13
class Logger1 {

private static Logger1 instance;

private Logger1(){}

public static Logger1 getInstance(){
if(instance == null){
instance = new Logger1();
}
return instance;
}
}

2.懒汉(线程安全)

1
2
3
4
5
6
7
8
9
10
11
12
13
class Logger2 {

private static Logger2 instance;

private Logger2(){}

public static synchronized Logger2 getInstance(){
if(instance == null){
instance = new Logger2();
}
return instance;
}
}

3.饿汉

1
2
3
4
5
6
7
8
9
10
class Logger3 {

private static Logger3 instance = new Logger3();

private Logger3(){}

public static synchronized Logger3 getInstance(){
return instance;
}
}

4.饿汉变种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Logger4 {

private static Logger4 instance;

static {
instance = new Logger4();
}

private Logger4(){}

public static synchronized Logger4 getInstance(){
return instance;
}
}

5.静态内部类

1
2
3
4
5
6
7
8
9
10
11
12
class Logger5 {

private static class LoggerHolder{
private static final Logger5 INSTANCE = new Logger5();
}

private Logger5(){}

public static synchronized Logger5 getInstance(){
return LoggerHolder.INSTANCE;
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Client {
public static void main(String args[]){

Logger1 logger1 = Logger1.getInstance();
Logger2 logger2 = Logger2.getInstance();
Logger3 logger3 = Logger3.getInstance();
Logger4 logger4 = Logger4.getInstance();
Logger5 logger5 = Logger5.getInstance();

System.out.println(logger1);
System.out.println(logger2);
System.out.println(logger3);
System.out.println(logger4);
System.out.println(logger5);
}
}

总结

参考链接:http://cantellow.iteye.com/blog/838473

优缺点

1.懒汉(线程不安全)

这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。

2.懒汉(线程安全)

线程安全,但是效率很低,99%情况下不需要同步

3.饿汉

基于classloder机制避免了多线程的同步问题,但是有可能调用Singleton的其他方法,就会被初始化,没有真正达到lazy loading的效果

4.饿汉变种

和第三种差不多,只不过采用静态内部类的实现方式

5.静态内部类

真正的lazy loading的单例实现

其他

参考链接中还提到了其他2种实现方式,因在工作中不是特别常用,就不予以说明了

  • 枚举
  • 双重校验锁