单例模式属于创建型模式,负责创建对象,确保始终创建的对象是唯一的,是单个的(内存地址唯一性)。
单例模式有两种懒汉是和饿汉式
创建方式:
1 私有的构造方法
2 对象唯一性采用static
3 对外提供公开访问对象方法
饿汉式
public class SingletonTest { private SingletonTest(){} private static SingletonTest1 singleton = new SingletonTest(); public static SingletonTest1 getSingleton(){ return singleton; } }
类加载时对象就已经被创建出来,浪费内存,static确保对象的个数是唯一,多线程下线程是安全。
懒汉式
public class SingletonTest { private SingletonTest(){} private static SingletonTest singleton = null; public static SingletonTest getSingleton(){ if(singleton == null){ return singleton; } }
单线程下线程安全,多线程下线程不安全。
我们进行优化,采用synchronized关键字加锁
public static synchronized SingletonTest getSingleton(){
if(singleton == null){
return singleton;
}
}
这样子效率太低,多线程下,每次都得线程锁的释放,排队。
采用双重锁进行优化
public class SingletonTest{ private SingletonTest(){} private static SingletonTest singleton = null; public static SingletonTest getSingleton(){ if(singleton == null){ synchronized (SingletonTest.class){ if(singleton == null){ singleton = new SingletonTest2(); } } } return singleton; } }
多线程下效率也高,当多个线程同时进入到 if(singleton == null) 这儿,发现该对象为null , 此时线程进行排队, 然后进行锁的释放,之后别的线程在进入的时候,在进行判断发现对象不为null,直接跳出判断,下一次直接走最外层判断,从而提高效率。
看了网上大神的博客,可以用静态内部类来创建单例
/** *@description: 静态内部类写法 *@author: wangl *@time: 2019/2/14 17:23 *@version 1.0 */ public final class Singleton{ private static class Sigle{ private static final Singleton S1 = new Singleton (); } private Singleton (){} public static final Singleton getSigle(){ return Sigle.S1; } public static void main(String[] args) { System.out.println(Singleton .getSigle()); System.out.println(Singleton .getSigle()); System.out.println(Singleton .getSigle()); System.out.println(Singleton .getSigle()); } }
运行如下
com.example.bwjf.demo.sss@1d56ce6a
com.example.bwjf.demo.sss@1d56ce6a
com.example.bwjf.demo.sss@1d56ce6a
com.example.bwjf.demo.sss@1d56ce6a
也可以达到效果,静态内部类,这种和饿汉式原理相似。都是在类加载的时候创建出对象。