婚纱摄影网站设计案例,遵义本地网,wordpress 多数据库,凡客包包多线程进阶#xff08;一#xff09; 文章目录 多线程进阶#xff08;一#xff09;单例模式饿汉模式懒汉模式 本篇主要引入多线程进阶的单例模式#xff0c;为后面的大冰山做铺垫 代码案例介绍
单例模式
非常经典的设计模式 啥是设计模式 设计模式好比象棋中的 “棋谱”…多线程进阶一 文章目录 多线程进阶一单例模式饿汉模式懒汉模式 本篇主要引入多线程进阶的单例模式为后面的大冰山做铺垫 代码案例介绍
单例模式
非常经典的设计模式 啥是设计模式 设计模式好比象棋中的 “棋谱”. 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏. 软件开发中也有很多常见的 “问题场景”. 针对这些问题场景, 大佬们总结出了一些固定的套路. 按照这个套路来实现代码, 也不会吃亏. 单例 - 单个实例对象
在有些场景下希望有的类只能有一个对象不能有多个在这样的场景下就可以使用单例模式了。
举个有意思的例子就是你只能娶一个老婆不过你可以生很多娃娃就不一定是单例的 在代码中有很多用于管理数据的对象就应该是”单例“的例如mysql JDBC DataSource描述mysql服务器的位置 那么这里有个问题 单例这个事情还需要设计模式吗 当我们写代码的时候只给这个类new一次对象不去new多次不就行了 实际上设计模式是非常必要的这其实上是属于设计模式这完全就是取决于程序员的编程素养。 不过俗话说宁可相信世界上有鬼也不能相信人的这张破嘴人是非常不靠谱的。 这样的思想方法在很多地方都会涉及到
finalintrefaceOverridethrows
于是此时就需要让编译器帮我们做监督确保这个对象不会出现多个new(出现多个的时候就直接编译报错)
饿汉模式
类加载的同时, 创建实例.
// 饿汉模式
class Singleton{private static Singleton instance new Singleton();//通过这个方法来获取到刚才的实例//后续如果想使用这个类的实例都通过 getInstance 方法来获取public static Singleton getInstance(){return instance;}//把构造方法设置为私有此时类外面的其他代码就无法 new 出这个类的对象private Singleton(){}
}public class Demo21 {public static void main(String[] args) {//此外又有一个实例这就不是单例了//Singleton s1 new Singleton();Singleton s1 Singleton.getInstance();Singleton s2 Singleton.getInstance();System.out.println(s1 s2);//true}
}懒汉模式
相比于饿汉模式他就比较从容在第一次使用的时候再去创建实例
//懒汉模式class SingletonLazy{private static volatile SingletonLazy instance null;public static SingletonLazy getInstance(){if (instance null) {if (instance null) {instance new SingletonLazy();}}return instance;}private SingletonLazy(){}
}public class Demo22 {public static void main(String[] args) {//此外又有一个实例这就不是单例了//Singleton s1 new Singleton();SingletonLazy s1 SingletonLazy.getInstance();SingletonLazy s2 SingletonLazy.getInstance();System.out.println(s1 s2);//true}
}我们举个例子
文本编辑器 记事本 需要打开一个非常大的文件 先把所有的内容都加载到内存中然后再显示内容加载过程会很慢只加载一小部分数据到内存立即显示内容随着用户翻页再动态加载其他内容懒汉模式 那么这里我们抛出一个问题 以上两种模式的写法是否是线程安全的如果有多个线程同时调用getInstance是否会出问题 如果多个线程同时修改同一个变量此时就可能出现线程安全问题
如果多个线程同时读取同一个变量这个时候就没什么事情不会有安全问题
那么我们看看饿汉模式的代码
public static Singleton getInstance(){return instance;}饿汉模式下的getInstance只是进行读取不是修改那么他也就没有线程安全的问题了~
那我们看看懒汉模式的代码
if(instance null){instance new SingletonLazy();
}
return instance;它既会读取又会修改就可能存在问题~ 那么我们怎么保证懒汉模式是线程安全的呢
类似于下面这种改法吗
public static SingletonLazy getInstance(){if (instance null) {synchronized (SingletonLazy.class) {if (instance null) {instance new SingletonLazy();}}}return instance;}当然不是我们要明确一个事情就是锁不是加了就安全
加的位置对不对才是关键
锁的{}的范围是合理的能够把需要作为整体的每个部分都囊括进去锁的对象也得是能够起到合理的锁竞争的效果
这样才是真正的加锁
所以修改如下
public static SingletonLazy getInstance(){synchronized (SingletonLazy.class) {if (instance null) {if (instance null) {instance new SingletonLazy();}}}return instance;}把if和new合并成一个整体此时的线程安全就迎刃而解了
不过一旦这么写的话后续每次调用getInstance都需要先加锁了 不过这种操作属实是画蛇添足了加锁是一个开销很大的操作加锁就可能会涉及到锁冲突 一冲突就会引起阻塞等待。 还有就是一旦某个代码涉及到 加锁那么基本上就可以宣告这个代码和“高性能”无缘了~ 但是实际上懒汉模式线程安全的问题只是出现在最开始的时候对象还没开始new呢
一旦对象new出来了后续多线程调用getInstance就只有读操作就不会线程不安全了~
那么这里抛出一个问题
是否有什么办法可以让代码线程安全又不会对执行效率产生太多影响呢
欲知后事如何敬请期待下一篇博客~
主要是我临时有事等明天写完再更