单例模式
单例模式有以下特点:
1)单例类只能有一个实例。
2)单例类必须自己创建自己的唯一实例。
3)单例类必须给所有其他对象提供这一实例。
4)单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
懒汉式单例模式(线程安全)
特点是:延迟加载,直到用到的时候才会加载。
import java.io.IOException; import java.math.BigDecimal; /** * * @Description :懒汉单例模式 * @author Bush罗 * @date 2018年5月14日 * */ @SuppressWarnings("all") public class Main { public static void main(String[] args) { Singleton singleton1=new Singleton(); singleton1.getInstance(); Singleton singleton2=new Singleton(); singleton2.getInstance(); } } class Singleton { private static Singleton singleton; public synchronized static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); System.out.println(singleton); } return singleton; } }
Singleton new了两次但实际上只产生了一个Singleton的实例
饿汉式单例模式
特点:一开始就加载了,如果说懒汉式是“时间换空间”,那么饿汉式就是“空间换时间”,因为一开始就创建了实例,所以每次用到的之后直接返回就好了。
import java.io.IOException; import java.math.BigDecimal; /** * * @Description :饿汉单例模式 * @author Bush罗 * @date 2018年5月14日 * */ @SuppressWarnings("all") public class Main { public static void main(String[] args) { Singleton singleton1=new Singleton(); singleton1.getInstance(); Singleton singleton2=new Singleton(); singleton2.getInstance(); } } class Singleton { private static Singleton singleton =new Singleton(); public synchronized static Singleton getInstance() { System.out.println(singleton); return singleton; } }
获取到的实例都是同一个
静态内部类的单例模式(线程安全,推荐)
为什么可以实现线程安全?
加载一个类时,其内部类不会同时被加载,内部类要被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。内部类加载的时候就实例化一次Singleton 。
特点:不用 synchronized ,节省时间。
调用 getInstance() 的时候才会创建对象,不调用不创建,节省空间,与懒汉式类似。
import java.io.IOException; import java.math.BigDecimal; /** * * @Description :静态内部类单例模式 * @author Bush罗 * @date 2018年5月14日 * */ @SuppressWarnings("all") public class Main { public static void main(String[] args) { //调用类的静态方法实例化该类,只会在第一次时实例化 Singleton singleton1=Singleton.getInstance(); System.out.println(singleton1); Singleton singleton2=Singleton.getInstance();; System.out.println(singleton2); } } class Singleton { //静态内部类 private static class SingletonHolder{ private static final Singleton INSTANCE = new Singleton(); } //对外提供公共的的访问方法 public synchronized static Singleton getInstance() { return SingletonHolder.INSTANCE; } }