单例模式
单例模式
多个线程操作同一对象,要保证对象的唯一性
解决方案
实例化过程只实例化一次
提供返回实例的方法
分类
public class HungrySingleton {
//加载的时候就产生了实例对象
private static HungrySingleton Instanse = new HungrySingleton();
private HungrySingleton() {
}
// 返回实例对象
public static HungrySingleton getInstanse() {
return Instanse;
}
}
- 线程安全性 : 再加载的时候已经被实例化,只有这一次,线程安全的
- 懒加载 : 没有延迟加载[占用内存空间],影响部分性能
- 性能比较好
public class HoonSingleton {
private static HoonSingleton Instance = null;
private HoonSingleton() {
}
public static HoonSingleton getInstance() {
if(null == Instance){ // 两个线程同时执行到这块,可能同时生成两个新对象
Instance= new HoonSingleton();
}
return Instance;
}
}
- 线程安全性 : 非线程安全的(不能保证对象的唯一性)
- 懒加载
- 懒汉式+同步方法
public class HoonSingleton {
private static HoonSingleton Instance = null;
private HoonSingleton() {
}
public synchronized static HoonSingleton getInstance() {
if(null == Instance){ // 两个线程同时执行到这块,可能同时生成两个新对象
Instance= new HoonSingleton();
}
return Instance;
}
}
- 线程安全性: 线程安全[锁的粒度很大]
- 性能 : 并发线程可能变为串行
- Double check Locking
public class DCL {
private static DCL Instance = null;
private connection conn = null ;
private Socket socket = null ;
private DCL() {
}
public static DCL getInstance() {
if (null == Instance) { //这里可能有线程同时进入
synchronized (DCL.class) {
if (null == Instance) {//这里肯定只能有一个线程进入,在这里再进行一次判空操作
Instance = new DCL();
}
}
}
return Instance;
}
- 线程安全性 :线程安全
- 懒加载
- 性能比较好
- 问题 : 会因为指令重排,出现指令重排
解决方案 :
Volatile + Double check Locking
private static volatile DCL Instance = null;
volatile 之前之后的代码不发生指令重排
public class HolderDemo {
private static class Holder {
private static HolderDemo Instance = new HolderDemo();
}// 实现了懒加载
//没有使用synchronized
//< init>
public static HolderDemo getInstance() {
return Holder.Instance;
}
}
- 懒加载 : 静态内部类中的 HolderDemo 的实例只有在调用的时候进行实例化
- 没有使用synchronized,效率高
Effective Java
public enum EnumSingleTon {
INSTANCE ; // 常量 ,在加载实例化一次,
public static EnumSingleTon getInstance(){
return INSTANCE;
}
}
public class EnumSingletonDemo {
private EnumSingletonDemo() {
}
private enum EnumHolder {
INSTANCE;
private EnumSingletonDemo instance;
EnumHolder() {
this.instance = new EnumSingletonDemo();
}
private EnumSingletonDemo getInstance() {
return instance;
}
}
public static EnumSingletonDemo getInstance() {
return EnumHolder.INSTANCE.instance;
}
}
- 实现了懒加载
- 充分利用了enum 中的对象为常量,只实例化一次