单例设计模式和动态代理设计模式

解决的问题

一个应用范围内,一个class类,只应该存在一个对象。

单列设计模式的特点

1.构造私有(不能通过正常手段进行new对象—因为通过反射还可以私有的方法进行调用)
2.静态成员变量(存储单列对象的引用)
3.提供一个公开静态的访问方法,获取单列对象

两种方式

懒汉式:会存在线程安全问题(面试最常问的就是这个)
饿汉式:不存在线程安全问题

饿汉式和懒汉式的区别

饿汉式,是不管你用不用该对象,都创建。
——会照成资源的浪费。
——在创建对象的时候,不会出现多线程情况。
在这里插入图片描述
懒汉式,只有第一次访问的时候,才会创建。
——也叫延迟加载,由于被加载的时候,肯存在多线程访问,加上被访问的类中有成员变量。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

单例模式常见的规范写法

1.双重检查锁(DCL)+volatile
2.静态内部类

饿汉模式的单列对象,什么时候创建?
当单例对象所对应的类被初始化的时候,才会创建该单例对象!!
类的初始化时机有哪些?通过new Student,通过访问static成员变量。。

在JVM加载类的时候,由JVM对加载类的线程加锁,也就是说类加载的时候,是线程安全的。不会存在线程安全问题。

如何判断线程安全问题?
1:是否存在多线程 是
2:是否有共享数据 是
3:是否存在非原子性操作 (是针对字节码指令)

原子性的理解

new Student(); i++;
是否是一个原子性操作呢? 不是的

如何保证原子性呢?加锁

volatile的第一个作用:可以禁用cpu缓存或者说工作内存

可见性的理解:
在这里插入图片描述
有序性的理解:
int x ; boolean a;
x= 20; step3 a = false; step4
x和a之间是没有依赖性(有没有happened-before关系)
所以说,JVM会考虑性能问题,有可能对step3和step4进行指令重排序。

int x = 10; int y ;
y = x+10;

猜你喜欢

转载自blog.csdn.net/yang13676084606/article/details/107418733