JAVA设计模式之【单例模式】
https://img-blog.csdnimg.cn/img_convert/ed5a1a778dfc2c4f5b5ebaaa03480a31.png1 类图
https://img-blog.csdnimg.cn/img_convert/2c2ac383fce5c04b703e90bb9bbedcea.png
2 饿汉式单例
比方:静态块、静态成员
2.1 概念
类加载的时候就立即初始化,而且创建单例对象
2.2 长处
没有加任何的锁、实验效率比力高
2.3 缺点
类加载的时候就初始化,不管用与不用都占着空间,浪费了内存。
3 懒汉式单例
3.1 直接:线程不安全
public class LazySimpleSingleton {
private LazySimpleSingleton(){}
//静态块,公共内存区域
private static LazySimpleSingleton lazy = null;
publicstatic LazySimpleSingleton getInstance(){
if(lazy == null){
lazy = new LazySimpleSingleton();
}
return lazy;
}
}
3.2 同步方法
public class LazySimpleSingleton {
private LazySimpleSingleton(){}
//静态块,公共内存区域
private static LazySimpleSingleton lazy = null;
public synchronized static LazySimpleSingleton getInstance(){
if(lazy == null){
lazy = new LazySimpleSingleton();
}
return lazy;
}
}
3.2.1 优化CPU:双重检查锁
public class LazyDoubleCheckSingleton {
private volatile static LazyDoubleCheckSingleton lazy = null;
private LazyDoubleCheckSingleton(){}
public static LazyDoubleCheckSingleton getInstance(){
if(lazy == null){
synchronized (LazyDoubleCheckSingleton.class){
if(lazy == null){
lazy = new LazyDoubleCheckSingleton();
//1.分配内存给这个对象
//2.初始化对象
//3.设置lazy指向刚分配的内存地址
//4.初次访问对象
}
}
}
return lazy;
}
}
3.2.2IDEA 情况下的多线程调试
3.3 静态内部类
这种形式兼顾饿汉式的内存浪费,也兼顾synchronized性能题目,完美地屏蔽了这两个缺点
//史上最牛B的单例模式的实现方式
public class LazyInnerClassSingleton {
//默认使用LazyInnerClassGeneral的时候,会先初始化内部类
//如果没使用的话,内部类是不加载的
private LazyInnerClassSingleton(){
if(LazyHolder.LAZY != null){
throw new RuntimeException("不允许创建多个实例");
}
}
//每一个关键字都不是多余的
//static 是为了使单例的空间共享
//保证这个方法不会被重写,重载
public static final LazyInnerClassSingleton getInstance(){
//在返回结果以前,一定会先加载内部类
return LazyHolder.LAZY;
}
//默认不加载
private static class LazyHolder{
private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();
}
}
3.3.1 反射粉碎单例
在构造函数上抛出异常
private LazyInnerClassSingleton(){
if(LazyHolder.LAZY != null){
throw new RuntimeException("不允许创建多个实例");
}
}
3.3.2 序列化粉碎单例
增加 readResolve()方法
public class SeriableSingleton implements Serializable {
publicfinal static SeriableSingleton INSTANCE = new SeriableSingleton();
private SeriableSingleton(){}
public static SeriableSingleton getInstance(){
return INSTANCE;
}
privateObject readResolve(){
returnINSTANCE;
}
}
4 注册式单例
4.1 罗列式单例
利用jdk特性。具有线程安全、实例唯一(杜绝反序列化破坏单例)的特点。
public enum EnumSingleton {
INSTANCE;
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static EnumSingleton getInstance(){
return INSTANCE;
}
}
4.1.1 长处
线程安全、实例唯一
4.2 容器缓存写法
public class ContainerSingleton {
private ContainerSingleton(){}
private static Map<String,Object> ioc = new ConcurrentHashMap<String,Object>();
public static Object getInstance(String className){
synchronized (ioc) {
if (!ioc.containsKey(className)) {
Object obj = null;
try {
obj = Class.forName(className).newInstance();
ioc.put(className, obj);
} catch (Exception e) {
e.printStackTrace();
}
return obj;
} else {
return ioc.get(className);
}
}
}
}
4.2.1 长处
对象方便管理、懒加载
4.2.2 缺点
不加上synchronized存在线程安全题目
5 ThreadLocal-线程单例
5.1 写法
public class ThreadLocalSingleton {
private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =
new ThreadLocal<ThreadLocalSingleton>(){
@Override
protected ThreadLocalSingleton initialValue() {
return new ThreadLocalSingleton();
}
};
private ThreadLocalSingleton(){}
public static ThreadLocalSingleton getInstance(){
return threadLocalInstance.get();
}
}
5.2 长处
保证在单个线程中是唯一
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]