Java 设计模式之单例模式
什么是单例模式?
单例模式即一个类在程序中永远只有一个实例。
单例的写法。
饿汉式(静态常量)
饿汉式(静态代码块)
懒汉式(线程不安全)
懒汉式(线程安全,同步方法)
懒汉式(线程安全,同步代码块)
双重检查
静态内部类
枚举
上代码。
饿汉式(静态常量)
//优点:写法简单,类加载时实例化,避免线程同步问题。 //缺点:类加载时实例化,无法达到懒加载的效果。浪费内存。 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } //提供静态变量 private static final SingleObj instance = new SingleObj(); //返回实例 public static SingleObj getInstance(){ return instance; } }
饿汉式(静态代码块)
//优缺点和上面一样,只是写法不同 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } //提供静态变量 private static SingleObj instance; //静态代码块执行时创建实例。 static { instance = new SingleObj(); } //返回实例 public static SingleObj getInstance(){ return instance; } }
懒汉式(线程不安全)
//优点:懒加载,使用时才会new //缺点:线程不安全,当多线程同时到if时,会创建多个实例。 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } //提供静态变量 private static SingleObj instance; //返回实例 public static SingleObj getInstance(){ //如果instance为空 则new一个 if (instance==null){ instance = new SingleObj(); } return instance; } }
懒汉式(线程安全,同步方法)
//优点:解决了线程不安全问题。 //缺点:每次调用getInstance()都要同步,效率低。 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } //提供静态变量 private static SingleObj instance; //返回实例 方法同步synchronized public static synchronized SingleObj getInstance(){ if (instance==null){ instance = new SingleObj(); } return instance; } }
懒汉式(线程安全,同步代码块)
//这种方法是为了解决上面每次调用的同步问题,把synchronized加在了代码块中。 //而在多线程同时运行到if中时,仍然会产生多个实例。不推荐使用 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } //提供静态变量 private static SingleObj instance; //返回实例 代码块同步 public static SingleObj getInstance(){ if (instance==null){ synchronized (SingleObj.class){ instance = new SingleObj(); } } return instance; } }
双重检查
//优点:线程安全,懒加载。 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } //提供静态变量 volatile - 保证变量的内存可见性 - 禁止指令重排序 private volatile static SingleObj instance; //返回实例 public static SingleObj getInstance(){ //进行两次判断 if (instance==null){ synchronized (SingleObj.class){ if (instance==null){ instance = new SingleObj(); } } } return instance; } }
静态内部类
//优点:懒加载(调用getInstance()时,才会加载内部类实例化),线程安全 public class SingleObj { //私有化构造方法,防止外部new private SingleObj(){ } private static class SingleInstance{ private static final SingleObj instance = new SingleObj(); } //返回实例 public static SingleObj getInstance(){ return SingleInstance.instance; } }
枚举
public enum SingleObj { instance; public void hello(){ } }