概述
这种模式设计到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象方式,可以直接访问,不需要实例化该类的对象。
单例模式的实现
- 饿汉式:即类的初始化阶段就创建单例对象
package com.syn.single;
public class Hungry {
/*构造方法私有化*/
private Hungry(){}
/*类中创建对象*/
private static Hungry hungry = new Hungry();
/*提供给外界获取对象的窗口*/
public static Hungry getInstance(){
return hungry;
}
}
- 懒汉式:首次被调用时才创建单例对象
package com.syn.single;
public class Lazy {
/*私有构造方法*/
private Lazy(){};
/*声明单例变量*/
private static Lazy lazy;
/*对外提供方法,并加上同步锁*/
public static synchronized Lazy getInstance(){
if (lazy == null) {
lazy = new Lazy();
}
return lazy;
}
}
- 懒汉式-双重检查方式:
package com.syn.single;
public class LazyDouCheck {
/*私有构造方法*/
private LazyDouCheck(){};
/*声明单例变量*/
private static volatile LazyDouCheck lazyDouCheck;
/*对外提供方法,并加上同步锁*/
public static LazyDouCheck getInstance(){
/*第一次判断,如果部位null,则直接返回已创建的单例对象*/
if (lazyDouCheck == null) {
/*此处锁住类*/
synchronized (LazyDouCheck.class){
/*抢到锁之后再次判断是否为null*/
if (lazyDouCheck == null){
lazyDouCheck = new LazyDouCheck();
}
}
}
return lazyDouCheck;
}
}
- 饿汉式(恶汉式)- 枚举类:
package com.syn.single;
public enum Evil {
INSTANCE;
}
破坏单例模式解决方案
1.序列化与反序列化破坏解决
package com.syn.single;
public class Lazy {
/*私有构造方法*/
private Lazy(){};
/*声明单例变量*/
private static Lazy lazy;
/*对外提供方法,并加上同步锁*/
public static synchronized Lazy getInstance(){
if (lazy == null) {
lazy = new Lazy();
}
return lazy;
}
/*反序列化时被调用,如果定义了这个方法,就返回这个方法的值,反之则new新对象*/
public Object readResolve(){
return Lazy.lazy;
}
}
2.反射破坏解决
package com.syn.single;
public class Lazy {
private static boolean flag = false;
/*私有构造方法*/
private Lazy(){
/*处理多线程问题*/
synchronized (Lazy.class){
/*根据flag判断对象是否已经创建*/
if (false){
throw new RuntimeException("不能创建多个对象");
}
flag = true;
}
};
/*声明单例变量*/
private static Lazy lazy;
/*对外提供方法,并加上同步锁*/
public static synchronized Lazy getInstance(){
if (lazy == null) {
lazy = new Lazy();
}
return lazy;
}
}