1.序言
本文旨在 开始讨论 多线程的代码案例编写——设计模式
单例模式是一种设计模式,属于程序员的棋谱
可以提高新手的下限
- 框架——硬性要求
- 设计模式——软性要求
都是为了更容易编写代码——“呆板” 对于程序员来说 是褒义词
1.1单例模式
单例模式是设计模式中 最典型的模式,比较简单,校招最容易考
单例:单个实例(对象)
强制要求,某个类,在某个程序中,只有唯一一个实例(不允许创建多个实例 new 多次)
1.2饿汉模式
饿——急迫 尽量早创建实例
//饿汉模式
class Singleton{
private static Singleton instance =new Singleton();
public static Singleton getInstance(){
return instance;
}
private Singleton(){
}
}
代码解释
private static Singleton instance =new Singleton();
静态成员的初始化,是在类加载的阶段触发的
类加载往往就是在程序一启动就触发——体现出急迫
public static Singleton getInstance(){ return instance; }后续通过getIstance() 方法获取实例
private Singleton(){ }单例模式的点睛之笔——在类外进行new操作 都会编译失败

s1 s2 引用同一个对象 结果为true

无法创建额外对象——实现单例模式
1.3懒汉模式
懒——尽量晚创建实例(甚至可能不创建了) 延迟创建
懒 意味着高效率
假设有一个大型文件(千万字的小说)
编辑器打开 方式二选一
- 把所有的内容,都从文件加载到内存中,都显示——明显卡顿 用户无法短时间全部接受
- 只把一部分内容加载并显示——后续如果用户翻页 随时加载后续数据
代码解释:
class Singletonlazy{
private static Singletonlazy instance =null;
public static Singletonlazy getInstance() {
if (instance == null) {
instance = new Singletonlazy();
}
return instance;
}
private Singletonlazy(){
}
}
public static Singletonlazy getInstance() { if (instance == null) { instance = new Singletonlazy(); } return instance; }懒汉模式下——实例的创建时机是 第一次使用 (不是程序启动时)
2.保证线程安全下的单例模式
上文的饿汉 懒汉模式代码 是否线程安全?如果不是 该怎么办——【经典面试题】
2.1饿汉模式

饿汉模式中——String 不可变对象 天然线程安全
2.2懒汉模式

条件修改 是非原子操作 会造成 线程不安全
2.2.1懒汉模式的优化步骤:
1.先为条件修改操作 加锁
创建锁对象 locker 使用sychronized

2. 添加 判断是否需要加锁

此处两个IF 判断条件 含义不同 ——恰好条件相同
第一个IF 是判断 是否需要加锁 执行加锁操作
第二个IF 是判断 是否需要创建实例
3.避免 内存可见性问题——添加Volatile
既然线程存在 对 instance 的修改操作
容易存在 T1线程读取instance T2线程进行修改 的情况
故 为 instance 添加volatile 关键字

Volatile的作用有两方面:
- 确保每次读取操作都是读内存,
- 关于该变量的读取和修改操作,不会触发重排序
instance = new Singletonlazy(); 此处代码容易 出问题

4.优化小结
优化步骤如图所示

308

被折叠的 条评论
为什么被折叠?



