设计模式:解决一些固定场景的固定套路,是一种代码风格的知道指南。设计模式不止23种
1、单例设计模式
单例设计模式:确保一个类只有一个实例,提供全局访问点
单例模式的实现方式:
1:饿汉模式
java
/**
* 饿汉模式
*/
class SingletonPattern {
private static SingletonPattern instance = new SingletonPattern();
private SingletonPattern () {
// 设置为private,外部类就不能通过new创建实例
}
public static SingletonPattern getInstance() {
return instance;
}
}
public class SinglePattern {
public static void main(String[] args) {
SingletonPattern instance1 = SingletonPattern.getInstance();
SingletonPattern instance2 = SingletonPattern.getInstance();
System.out.println(instance1 == instance2); // true
}
}
2:懒汉模式
懒汉模式(线程不安全)
此处的代码是存在线程安全问题的。
1:原子性
应该将此处代码打包成原子的,不让代码穿插操作。所以就对代码进行加锁,解决原子性问题
if(instance == null) {
instance = new SingleLazy();
}
2:指令重排序

instance = new SingleLazy(); 此处这个new操作实际有好几步指令,粗略分为下面三步
1:内存分配
2:初始化零值
3:执行构造函数
实际的执行顺序是1-》2-》3,但是编译器优化的指令重排序,可能会将原本执行顺序重排为1-》3-》2,所以为了避免指令重排序,需要在instance上加上volatile
java
class SingleLazy {
/**
* 单例模式
* 懒汉模式:创建实例的时机比较晚,不是那么急迫
*/
private static SingleLazy instance = null;
private SingleLazy() {
}
// 第一次使用实例的时候,才创建实例
public static SingleLazy getInstance() {
if(instance == null) {
// return new SingleLazy(); // 这样写是错的,这样每次get都会new
instance = new SingleLazy();
}
return instance;
}
}
public class SingleLazyPattern {
public static void main(String[] args) {
SingleLazy instance1 = SingleLazy.getInstance();
SingleLazy instance2 = SingleLazy.getInstance();
System.out.println(instance1 == instance2); // true
}
}
懒汉模式(线程安全)
又在锁的外面加了一条判断,目的就是只在第一次调用getInstance方法是进行加锁,避免重复加锁
if(instance == null)
// 如果不进行判断,那么每次调用getInstance方法都会进行加锁操作
// 但是如果加了判断,只会在第一次调用getInstance方法进行加锁操作
java
class SinglePattern {
private static volatile SinglePattern instance = null; // volatile解决指令重排序问题
private static Object lock = new Object();
private SinglePattern() {
// 避免外部创建实例
}
public static SinglePattern getInstance() {
if(instance == null) {
// 如果不进行判断,那么每次调用getInstance方法都会进行加锁操作
// 但是如果加了判断,只会在第一次调用getInstance方法进行加锁操作
synchronized(lock) { // 加锁,解决原子性问题
if(instance == null) {
instance = new SinglePattern();
}
}
}
return instance;
}
}
public class SingleLazyPattern {
public static void main(String[] args) {
SinglePattern instance1 = SinglePattern.getInstance();
SinglePattern instance2 = SinglePattern.getInstance();
System.out.println(instance1 == instance2);
}
}