单例模式(创建型)
程序员文章站
2022-07-13 23:44:28
...
特点:一个类只能有一个实例对象。
单例实现要求:
- 静态单例实例对象
- 私有构造方法
- public 静态函数用以返回实例对象
1. 懒汉式单例
---线程不安全单例
public class Singleton
{
private static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton()
{
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
---线程安全单例
public class Singleton
{
private static Singleton singleton;
private Singleton(){}
public static synchronized Singleton getSingleton()
{
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
2. 饿汉式单例(线程安全)
public class Singleton
{
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getSingleton()
{
return singleton;
}
}
3. 双重校验锁(线程安全)
public class Singleton
{
private static volatile Singleton singleton;
private Singleton(){}
public static Singleton getSingleton()
{
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
volatile关键字的作用是防止JVM在进行new Singleton()操作时进行指令重排从而导致多线程操作中获取到未初始化完全的Singleton对象实例。
4. 静态内部类(线程安全)
public class Singleton
{
private static class SingletonHolder{
private static final Singleton singleton = new Singleton();
}
private Singleton(){}
public static Singleton getSingleton()
{
return SingletonHolder.singleton;
}
}
5. 枚举(线程安全)
public enum Singleton
{
singleton;
public Singleton getSingleton(){
return singleton;
}
}
破坏单例的情况:
反射调用构造函数
序列化单例对象
解决方法
使用枚举方式建立单例模型
序列化:在单例类中添加readResolve()方法
public class Singleton implements Serializable
{
......
private Object readResolve(){
return singleton;
}
}
反射:重写构造函数,在第二次创建单例时抛出异常
public class Singleton implements Serializable
{
private static Singleton singleton;
private static boolean flag = false;
private Singleton(){
synchronized (Singleton.class){
if(flag == false){
flag = !flag;
}else{
throw new RuntimeException("单例模式已被创建");
}
}
}
public static Singleton getSingleton()
{
.......
}
}
上一篇: 创建型------单例模式
下一篇: 创建型(单例模式)