小记Java单例模式的各种实现

单例模式是我们编程中最常用的设计模式,小记练习一下:

1、饿汉法:


public class Singleton {

private static final Singleton instance = new Singleton();

private Singleton(){}

public static Singleton getInstance(){

return instance;

}

}

这是最简单的方法,在类引用的时候就会实例化。不能延迟加载,某种意义上会增加系统的负载。

2、懒汉法:


public class Singleton {

private static Singleton instance = null;

private Singleton(){}

public static Singleton getInstance(){

if(instance == null){

instance = new Singleton();

}

return instance;

}

}

在饿汉法的基础上增加了延迟加载,只有调用getInstance的方法才会实例化对象,在单线程中没有问题,但在多线程中有可能导致多次实例化。

3、多线程安全型:


public class Singleton {

private static volatile Singleton instance = null;

private Singleton(){}

public static Singleton getInstance(){

synchronized (Singleton.class) {

if (instance == null) {

instance = new Singleton();

}

}

return instance;

}

}

在instance对象加上volatile关键字,保证其对所有的线程可见性,并禁止其对指令重排序优化。在判断null和new的部分进行加锁。但是每次调用的时候,都要通过synchronize锁机制排队等待,会有效率方面的问题。

4、多线程安全性兼顾效率(双重检查锁):


public class Singleton {

private static volatile Singleton instance = null;

private Singleton(){}

public static Singleton getInstance(){

if(instance == null) {

synchronized (Singleton.class) {

if (instance == null) {

instance = new Singleton();

}

}

}

return instance;

}

}

在synchronized关键字外层再加一个判断null,只有为null后才会进入方法内,可以减少绝大部分的锁操作。

==注意:volatile关键字在JDK 1.5之前无法完全保证指令优化重排序,所以在JDK1.5之前双重校验是有问题的==

5、静态内部类


public class Singleton {

private Singleton(){}

private static class Holder{

private static Singleton instance = new Singleton();

}

public static Singleton getInstance(){

return Holder.instance;

}

}

将创建的过程放在静态内部类中,静态内部类只有被调用的时候才会加载,所以符合延迟加载。静态内部类只会被加载一次,所以是线程安全的。

以上所有方式,在序列化的时候都需要额外的工作(Serializable、transient、readResolve()),否则在反序列化的时候都会创建一个新的实例。

6、枚举方式:


public enum Singleton {

INSTACE;

private String name;

public String getName() {

return name;

}

}

使用枚举方式实现的单例模式,自带线程安全和防止反射强行调用构造器,还提供了自动序列化的机制,防止反序列化的时候创建新的对象。

你可能感兴趣的:(小记Java单例模式的各种实现)