单例模式保证一个类仅有一个实例,并提供一个访问他的全局函数。当系统开发中某个类只能有一个实例时,就可以采用单例模式。
单例模式
单例模式是一种常用的软件设计模式。在他的核心 结构中只包含一个被称为单例的特殊类,保证系统中该类只有一个实例。
总之,单例模式具有以下特点:
- 单例类只能有一个实例
- 单例类必须自己创建自己唯一的实例
- 单例类必须给所有的其他对象都能提供这一实例。
保证单例模式仅有一个实例的核心思想是构造方法私有化,所以单例模式的方法主要有以下两种。
直接实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class Singleton1 { private static final Singleton1 SINGLETON_1 = new Singleton1(); private Singleton1() { System.out.println("初始化单例模式"); } public static Singleton1 getInstance() { return SINGLETON_1; } }
|
延迟实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
public class Singleton2 { private static volatile Singleton2 singleton2 = null;
private Singleton2() { System.out.println("初始化实例"); }
public static Singleton2 getInstance1() { if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; } }
|
与直接实例化不同,单例成员变量singleton2首先初始化为null,它在方法getInstance()内完成延迟实例化,并返回单例对象,但是该方法存在线程安全问题。如果两个线程都在执行getInstance()方法,线程一已经在执行if (singleton2 == null)
后,在执行完singleton2 = new Singleton2()
前,线程二正在执行if (singleton2 == null)
也成立,这样将会生成两个单例对象,违背了单例模式。
线程安全-synchronized完全同步方法
1 2 3 4 5 6
| public static synchronized Singleton2 getInstance2() { if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; }
|
使用synchronized关键字后,当多线程同时访问getInstance()方法的时候,多线程将穿行运行。
线程安全-synchronized部分同步方法
1 2 3 4 5 6 7 8 9 10 11
| public static Singleton2 getInstance3() { if (singleton2 == null) { synchronized (Singleton2.class){ if (singleton2 == null){ singleton2 = new Singleton2(); } } } return singleton2; }
|
此方法中,只有当对象还没实例化的时候会串行执行,其他的时候可并行运行。与完全同步方法相比,提高了运行效率。
线程安全-静态内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class Singleton3 { private Singleton3(){ System.out.println("实例初始化"); } private static class My{ private static final Singleton3 SINGLETON_3 = new Singleton3(); } public static Singleton3 getInstance(){ return My.SINGLETON_3; } }
|
与使用synchronized关键字的方法相比,此方法提高了Java虚拟机的维护效率,而且此方法还是线程安全的。
参考文献
欢迎您扫一扫上面的微信公众号,订阅我的博客!
上一篇:maven springboot集成mybatis构建项目
下一篇:在Hexo搭建的博客中插入音乐或者视频