主题
安全发布对象与设计模式
发布与逃逸
发布对象:使一个对象能够被当前范围之外的代码所使用
对象逸出:一种错误的发布。当一个对象还没有构造完成时,就使它被其他线程所见
安全发布对象的方法
1、在静态初始化函数中初始化一个对象引用
2、将对象的引用保存到volatile类型域或者AtomicReference对象中
3、将对象的引用保存到某个正确构造对象的final类型域中
4、将对象的引用保存到一个由锁保护的域中
设计模式
安全发布对象与许多其他设计模式都有关系,尤其是在多线程环境中需要考虑对象状态的一致性和线程安全性的情况下。
工厂模式(Factory Pattern): 工厂模式用于创建对象的实例,通过工厂方法或者工厂类来隐藏对象的创建细节。在多线程环境下,工厂模式可以确保通过工厂方法创建的对象实例是安全发布的,以保证对象的线程安全性。
观察者模式(Observer Pattern): 观察者模式用于定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。在多线程环境下,观察者模式可以通过使用线程安全的观察者列表来确保被观察者对象的状态安全发布。
享元模式(Flyweight Pattern): 享元模式用于减少对象的创建数量,通过共享相同的对象实例来节省内存和提高性能。在多线程环境下,享元模式可以确保共享的对象实例是线程安全的,以避免并发访问时的竞态条件和数据不一致性。
责任链模式(Chain of Responsibility Pattern): 责任链模式用于构建一条处理请求的责任链,每个处理者都可以处理请求或者将请求传递给下一个处理者。在多线程环境下,责任链模式可以确保请求在责任链上传递时的线程安全性,以保证请求的安全发布和正确处理。
代理模式(Proxy Pattern): 代理模式用于为其他对象提供一种代理以控制对该对象的访问。在多线程环境下,代理模式可以确保代理对象对被代理对象的访问是线程安全的,以保证对象的安全发布和访问控制。
设计模式中的许多模式都可以与安全发布对象相关联,以确保对象在多线程环境中的安全性和一致性。在实际应用中,根据具体的需求和场景选择合适的设计模式来确保对象的安全发布和线程安全性。
关于设计模式,可在公众号后台回复1010
线程安全的单例模式
饿汉模式
在类装载时进行创建
java
public class SingletonDemo {
private SingletonDemo() {}
// 单例对象
private static SingletonDemo instance = new SingletonDemo();
// 静态的工厂方法
public static SingletonDemo getInstance() {
return instance;
}
}
枚举模式
java
public class SingletonDemo2 {
private SingletonDemo2() {}
public static SingletonDemo2 getInstance() {
return Singleton.INSTANCE.getInstance();
}
private enum Singleton {
INSTANCE;
private SingletonDemo2 singleton;
// JVM保证这个方法绝对只调用一次
Singleton() {
singleton = new SingletonDemo2();
}
public SingletonDemo2 getInstance() {
return singleton;
}
}
public static void main(String[] args) {
System.out.println(SingletonDemo2.getInstance().hashCode());
}
}
双重同步锁
volatile + 双重检测机制 -> 禁止指令重排
1、分配对象的内存空间
2、初始化对象
3、设置instance指向刚分配的内存
java
public class SingletonDemo3 {
private SingletonDemo3() {}
private volatile static SingletonDemo3 instance = null;
// 静态的工厂方法
public static SingletonDemo3 getInstance() {
if (instance == null) { // 双重检测机制
synchronized (SingletonDemo3.class) { // 同步锁
if (instance == null) {
instance = new SingletonDemo3();
}
}
}
return instance;
}
}