package com.bingo.frame.oop.instance;
import java.util.HashMap;
import java.util.Map;
/**
* 对象单例设计
* @author bingo
*
*/
//单线程
class Singleton01{
private static Singleton01 instance;
//构造方法私有化
private Singleton01() {}
public static Singleton01 getInstance() {
if (instance == null) {
instance = new Singleton01();
}
return instance;
}
}
//双重验证的懒汉单例设计: 适用多线程, 并发量不是很大
class Singleton02{
/**
* volatile用于修饰属性
* 1)保证对象修改可见性
* volatile可以保证指令不会重排序, 对象创建严格按照顺序进行
* : 线程调用CPU对对内存中的对象进行操作, 默认会加载到CPU独有的Cache中(高速缓存),
* 多线程情况下一个线程修改对另一个线程不可见, volatile就是禁止使用CPU中的缓存,
* 使用操作系统内存存放对象, 使用同一份对象保证多个线程之间修改的可见性
*
* 2)禁止JVM指令重排序
* 对象创建步骤: a.分配内存 b.对象属性初始化,执行构造方法 c.将对象地址赋值给引用
* 如果jvm对指令进行重排序 acb 顺序执行,就会得到一个属性没有被初始化的对象
*
* 3)不能保证原子性(还是需要synchronized保证原子性)
*/
private static volatile Singleton02 instance;
private Singleton02() {}
public static Singleton02 getInstance() {
//双重判断减少多线程阻塞次数
if (instance == null) {
//静态方法对象锁是类的字节码对象
synchronized (Singleton02.class) {
if (instance == null) {
instance = new Singleton02();
}
}
}
return instance;
}
}
//饿汉单例(类加载时创建对象实例): 适用小对象, 频繁使用, 高并发
class Singleton03{
//类加载时初始化
private static Singleton03 instance = new Singleton03();
private Singleton03() {}
public static final Singleton03 getInstance() {
return instance;
}
}
//基于内部类实现懒汉单例: 适用大对象, 频繁使用, 高并发
class Singleton04{
static class Inner{
private static final Singleton04 instance = new Singleton04();
}
private Singleton04() {}
public static Singleton04 getInstance() {
return Inner.instance;
}
}
class A{}
class B{}
class ObjectContainer{
public static Map<String, Object> objectMap = new HashMap<String, Object>();
static {
objectMap.put("A", new A());
objectMap.put("B", new B());
}
public static Object get(String key) {
return objectMap.get(key);
}
}
/**
* 线程内部单例: 一个对象在被多个线程访问时, 每个线程单独拥有一份(ThreadLocal)
* @author bingo
* 参考: org.apache.ibatis.executor.ErrorContext
*/
class Singleton05{
private static final ThreadLocal<Singleton05> LOCAL = new ThreadLocal<Singleton05>();
private Singleton05() {
}
public static Singleton05 getInstance() {
Singleton05 context = LOCAL.get();
if (context == null) {
context = new Singleton05();
LOCAL.set(context);
}
return context;
}
}
public class TestObjectInstance03 {
public static void main(String[] args) {
System.out.println(ObjectContainer.get("A")==ObjectContainer.get("A"));
System.out.println("不能操之过急-_-");
}
}
对象单例设计
最新推荐文章于 2022-03-04 18:16:19 发布