保险网站有哪些保险网站,上海暂停娱乐场所营业通知,百度推广登录首页网址,家装设计效果图网站目录
单例模式
饿汉模式
懒汉模式 单例模式
所谓单例模式,就是在有些场景中,有些特定的类,只能创建一个实例(对象),当程序员不小心创建多个实例,就会出现编译报错.
★ 这种模式涉及到一个单一的类#xff0c;该类负责创建自己的对象#xff0c;同时确保只有单个对象被创…目录
单例模式
饿汉模式
懒汉模式 单例模式
所谓单例模式,就是在有些场景中,有些特定的类,只能创建一个实例(对象),当程序员不小心创建多个实例,就会出现编译报错.
★ 这种模式涉及到一个单一的类该类负责创建自己的对象同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式可以直接访问不需要实例化该类的对象。
★单例模式是一种创建型设计模式它确保一个类只有一个实例并提供了一个全局访问点来访问该实例。
注意
1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。
优点
1、在内存里只有一个实例减少了内存的开销尤其是频繁的创建和销毁实例比如管理学院首页页面缓存。2、避免对资源的多重占用比如写文件操作。
缺点没有接口不能继承与单一职责原则冲突一个类应该只关心内部逻辑而不关心外面怎么样来实例化。
使用场景 1、要求生产唯一序列号。2、WEB 中的计数器不用每次刷新都在数据库里加一次用单例先缓存起来。3、创建的一个对象需要消耗的资源过多比如 I/O 与数据库的连接等。
注意事项getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
单例模式又分为饿汉模式和懒汉模式 饿汉模式
所谓饿汉模式,就是在类加载阶段,就把实例创建出来,这种效果就给人一种特别急切的感觉,就称为单例模式.
实现方式 这个代码通过两个关键操作 保证实例是唯一的 ★static这个操作,是让当前的instance 属性是类属性,类属性是长在类对象上的,类对象有事唯一实例,所以保证了这个实例是唯一的 ★将构造方法设为private,外面的代码是无法通过new在来创建这个实例的
在多线程操作中,饿汉模式只有一个retutn操作,这只是一个读操作,是线程安全的 懒汉模式
这个实例并非在类加载的时候创建的,而是在第一次真正使用的时候,才去创建,避免内存的浪费. 在多线程操作中,懒汉模式既有读操作也有写操作 ,下面画图演示 在上面的操作中,多个线程读到的instance的值都是null,就会多次触发new 操作,此时就是线程不安全的.上面的线程安全问题,本质上是,读和写的操作不是原子的,导致t2线程读到的值是t1还没来得及修改的,可以通过加锁解决线程安全问题. 上面代码导致每次getInstance的时候都需要加锁,但加锁是有开销的,所以只需要在new 对象之前加锁是有必要的, 一旦new 对象之后,调用getInstance的值都是非空的,就会直接触发return 操作,相当于一个比较操作,一个返回操作,都是读操作,此时不加锁也没事,对上面代码在进行改进,当instance为空的时候在进行加锁 在上面的代码中还会出现内存可见性问题和指令重排序问题,在这里就要先理解一下Instance new SingletonLazy这个操作了,这个操作分为三步
1. 申请内存空间
2. 调用构造方法,把这个内存空间初始化成一个合理的值
3. 把内存空间的值赋给Instance引用.
此时编译器为了提高运行效率,可能会进行指令重排序,调整代码执行顺序,导致多线程操作出现问题. 理解双重 if 判定 和 volatile操作: ★ 加锁 / 解锁是一件开销比较高的事情 . 而懒汉模式的线程不安全只是发生在首次创建实例的时候 . 因此后续使用的时候, 不必再进行加锁了 . ★ 外层的 if 就是判定下看当前是否已经把 instance 实例创建出来了 . ★ 同时为了避免 内存可见性 导致读取的 instance 出现偏差 , 于是补充上 volatile . 当多线程首次调用 getInstance, 大家可能都发现 instance 为 null, 于是又继续往下执行来竞争锁 , 其中竞争成功的线程, 再完成创建实例的操作 . 当这个实例创建完了之后, 其他竞争到锁的线程就被里层 if 挡住了 . 也就不会继续创建其他实例 . 在对上面代码进行完善 至此一个完整版的懒汉模式就完成了