一、饿汉式
1.示例代码
public class HungrySingleClass {
private static HungrySingleClass hungrySingleClass = new HungrySingleClass();
private HungrySingleClass() {
}
/**
* 单例方法
* @return
*/
public static HungrySingleClass getInstance() {
return hungrySingleClass;
}
}
2.代码理解
- 先创建一个私有的构造函数(防止其它地方直接实例化),创建私有变量防止其他人访问
- 为什么要使用static关键字?由于构造器被私有,没办法创建类再访问getInstance方法,因此只能从类一级,即HungrySingleClass.getInstance()。由于静态方法只能访问静态变量,因此变量也需要使用static修饰
二、懒汉式
1.示例代码
public class LazySingleClass {
private volatile static LazySingleClass lazySingleClass = null;
private LazySingleClass() {
}
public static LazySingleClass getInstance() {
if(lazySingleClass == null) {
synchronized (LazySingleClass.class) {
if(lazySingleClass == null) {
lazySingleClass = new LazySingleClass();
}
}
}
return lazySingleClass;
}
}
2.代码理解
- 懒汉式只有当单例为空的时候才回去实例化单例的值
- 线程安全:由于懒汉式符合多个线程同时修改同一个变量,因此我们需要synchronized
- 优化:由于每次都需要去拿锁浪费效率,因此加入双重校验锁,在synchronized前面多添加一个if判断
- volatile关键字的作用:禁止指令初始化。实例化对象步骤为:为对象分配内存、初始化对象、将内存地址赋值给 instance 变量。指令初始化会导致步骤2、3颠倒。假设线程A正在实例化对象,当他进行实例化对象时,虽然内存地址赋值给了instance对象,但是并没有初始化,此时线程B进行第一个if条件判断,返回了一个并未完全初始化的对象。volatile关键字保证要么instance是null,要么是一个完整的对象
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。