目录
小二在学习的时候,偶尔看到单例模式的初级写法,便想着将自己目前了解到的单例模式的几种写法做一个小总结。
这里记录一下单例的几种写法和优缺点。
- 1.初级写法
- 2.加锁
- 3.饿汉式
- 4.懒汉式
- 5.双锁检验
- 6.内部类
1.初级写法
初级模式,便是在类内部声明一个私有的静态变量,并不实例化,实例化在一个静态方法中,通过判断变量是否为空,来觉得是否实例化,不过此种方法在高并发下会出现线程安全问题。
package cn.zzuli.edu.singleton;
/**
* 最普通的单例模式,此种方式在高并发下会出现线程安全问题
*/
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance(){
//高并发下出现线程安全问题的地方
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
2.加锁
在初级模式中,如果出现了线程安全问题。我们最能想到的便是加锁,使得线程安全问题除去。此种方法又称为懒汉式单例模式。
package cn.zzuli.edu.singleton;
/**
* 加锁的单例模式,解决了线程安全问题
*/
public class SSingleton {
private static SSingleton singleton;
private Ssingleton() {
}
public synchronized static Ssingleton getInstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
3.饿汉式
饿汉式的单例模式的最大特点。是类在加载时就直接初始化了实例。即使没有用到,也会实例化。
package cn.zzuli.edu.singleton;
/**
* 饿汉式的单例模式
* 类在加载时就直接初始化了实例。即使没有用到,也会实例化。
*/
public class EHSingleton {
//static修饰,在堆内存中只初始化一次,
private static final EHSingleton EH_SINGLETON = new EHSingleton();
private EHSingleton() {
}
//无写操作,只返回堆内存中的唯一一个
public static EHSingleton getInstance(){
return EH_SINGLETON;
}
}
4.懒汉式
懒汉式的单例模式,就是在会发生线程安全的类上加synchronized关键字, 使得方法变为同步方法,解决线程安全问题。
package cn.zzuli.edu.singleton;
/**
* 懒汉式的单例模式
* 就是在会发生线程安全的类上加synchronized关键字
* 使得方法变为同步方法,解决线程安全问题
*/
public class LHSingleton {
private static LHSingleton lhSingleton;
//构造方法私有化
private LHSingleton() {
}
//同步方法,线程安全,但是效率低下
public static LHSingleton getInstance(){
if (lhSingleton == null){
//在会发生线程安全问题的地方加锁
synchronized(LHSingleton.class){
lhSingleton = new LHSingleton();
}
}
return lhSingleton;
}
}
5.双锁检验
双加锁的单例模式
双重非空判断,new对象前加一次锁。
volatile关键字,考虑的是,new关键字在虚拟机中执行时其实分为很多步骤,
具体原因可以参考深入理解java虚拟机一书
(考虑的是这个new关键字字节码执行时是非原子性的),
而volatile关键字可以防止指令重排。
package cn.zzuli.edu.singleton;
/**
* 双加锁的单例模式
* 双重非空判断,new对象前加一次锁。
* volatile关键字,考虑的是,new关键字在虚拟机中执行时其实分为很多步骤,
* 具体原因可以参考深入理解java虚拟机一书
* (考虑的是这个new关键字字节码执行时是非原子性的),
* 而volatile关键字可以防止指令重排。
*/
public class SynSingleton {
private volatile static SynSingleton synSingleton;
private SynSingleton() {
}
public static SynSingleton getInstance(){
if (synSingleton == null){
synchronized (SynSingleton.class){
if (synSingleton == null) {
synSingleton = new SynSingleton();
}
}
}
return synSingleton;
}
}
6.内部类
内部类的单例模式
package cn.zzuli.edu.singleton;
/**
* 内部类的单例模式
*/
public class ICSingleton {
private ICSingleton() {
}
public static ICSingleton getInstance(){
return Singleton.icSingleton;
}
//内部类
private static class Singleton{
private static ICSingleton icSingleton = new ICSingleton();
}
}
小二了解的不多,帮帮我一下。
thx a lot。