一、懒汉模式
1.1对象在使用时创建
a.保证线程安全
b.优化加锁方式
class Singleton01 {
private Singleton01() {
}
private static Singleton01 instance;
/**
* 线程不安全
* 1)存在并发执行的线程
* 2)存在共享数据集
* 3)在共享数据集上的操作不是原子操作
*
* @return
*/
public static Singleton01 getInstance() {
if (instance == null) {
instance = new Singleton01();
}
return instance;
}
}
class Singleton02 {
private Singleton02() {
}
private static Singleton02 instance;
/**
* 悲观锁:某一时刻只能有一个线程执行代码内容
*
* @return
*/
public static synchronized Singleton02 getInstance() {
if (instance == null) {
instance = new Singleton02();
}
return instance;
}
}
/*
* static ReentrantLock lock=new ReentrantLock(false); public static Singleton02
* getInstance(){ try{ lock.lock(); if(instance==null){ instance=new
* Singleton02(); } return instance; }finally{ lock.unlock(); } }
*/
class Singleton03 {// 大对象,稀少用
private Singleton03() {
}
/**
* volatile 可以保证线程的可见性(当使用此修饰符 修饰一个属性时,只有一个线程改变了此属性的值, 对其它线程立刻可见。),但不能保证原子性。
*/
private static volatile Singleton03 instance;
private static Singleton03 getInstance() {
// 最坏情况的是所有线程都会进行此代码块
// 最好情况知有一个线程会 进入如下代码块
if (instance == null) {
synchronized (Singleton03.class) {
if (instance == null) {
instance = new Singleton03();
}
// ...其他操作
} // synchronized可以保证操作原子性,可见性
} // 减少阻塞线程的数量(通过双重判定)
return instance;
}
public static void show() {
};// 其他方法
}
二、饿汉模式
2.1对象在被类加载时创建
a.思考对象大小,
b.小对象可在类加载时创建
c.大对象要延迟加载
//饿汉模式在类加载时才初始化对象
class Singleton04 {
/** 对象在初始化此属性 */
private Singleton04() {
}// 小对象,频繁用
/**
* 类加载时会初始化此属性,而且只初始化1次
*/
private static Singleton04 instance = new Singleton04();
public static Singleton04 getInstance() {
return instance;
}
public static void show() {
}
}
class Singleton05 {
private int[] array = new int[2048];
private Singleton05() {
}
// 静态内部类(构建对象,访问类属性,获取方法时,会加载类)
static class Inner {// 使用内部类延迟对象创建
private static Singleton05 instance = new Singleton05();
}
// 对外的全局访问点(通过此方法获取对象)
public static Singleton05 getInstance() {
// 访问内部类的instance属性
return Inner.instance;
}
// 频繁访问show方法时,是不会加载Inner类的
public static void show() {
System.out.println("show()");
}
public void put(int a) {
array[0] = a;
}
}
enum Singleton06 {// Singleton06.class
instance;// 单例对象(类加载时创建,且只创建一次)
/*
* private Singleton06() {//不能使用public修饰 System.out.println("Singleton06()");
* }//默认就有一个私有的构造函数
*/
/**
* 外界如何访问此方法 Singleton06.instance.show();
*/
public void show() {
}
}