Java Design Pattern-Part II 单例模式

单例模式(8种方式):整个软件系统中只存在一个对象实例;如hibernatesessionfactory,充当数据源的代理并负责创建Session。由于SF不是轻量级的对象,一个项目通常只需要一个sessionfactory。JDK Runtime getRuntime() 是单例模式的饿汉式-静态常量方式创建。

使用场景:需要频繁销毁和创建、创建对象耗时/耗资源过多的工具类对象,重量级对象,频繁访问数据库或文件的对象(比如数据源、sessionfactory)


饿汉式-静态常量: 在类装载classloader时就完成了实例化,避免了线程同步的问题;可用

 1.过程:

  1. a.构造器私有化;
  2. b.类的内部创建私有final静态对象
  3. c.向外暴露静态公共方法,返回对象实例
class A{ 
private final static A ins = new A(); 
private A(){}; 
public static A getInstance(){return ins;}
}

2.缺点:可能造成内存浪费;达不到lazy loading的效果。


饿汉式-静态代码块:同上,可用

 1.过程:

  1. a.构造器私有化;
  2. b.类的内部声明私有静态对象变量
  3. c.静态代码块中初始化对象
  4. d.向外暴露静态公共方法,返回对象实例
class A { 
private static A ins; 
private A(){}; 
static{ ins = new A();} 
public static A getInstance(){return ins;}
}

2.缺点: 同上;


懒汉式-线程不安全:单线程下可实现懒加载;

 1.过程:

  1. a.构造器私有化;
  2. b.类的内部声明私有静态对象变量
  3. c.向外暴露静态公共方法,对象为空时创建对象,返回对象实例

Class A{ private static A ins ; private A(){}; public static A getInstance(){

if(ins == null){ins = new A(); return ins;}

}}

2.缺点:多个线程执行if null 判断时,线程不安全,实际开发禁止使用


懒汉式-同步方法:线程安全

 1.过程:

  1. a.构造器私有化;
  2. b.类的内部声明私有静态对象变量
  3. c.向外暴露静态公共singleton方法,对象为空时创建对象,返回对象实例
class A{ 
private static A ins; 
private A(){};
public static synchronized A getInstance(){

If(ins==null){ins = new A(); return ins;}}

}

2.缺点:效率低,实例化代码只需执行一次而不是每次调用都同步,之后获得实例只需直接调用return方法,实际开发不推荐使用;


懒汉式-同步代码块:不能实现线程安全

 1.过程:

  1. a.构造器私有化;
  2. b.类的内部声明私有静态对象变量
  3. c.向外暴露静态公共方法,对象为空时,同步代码块只包含创建对象语句,返回对象实例

Class A{ private static A ins; private A(){};

 public static  A getInstance(){

If(ins==null){ synchronized(A.class) {ins = new A();}

 return ins;}

}}

2.缺点:if语句判空仍然存在多线程不安全,无意义


双重检查锁volatile 修饰的变量一发生改变就立即将值更新到主存, 同步代码块保证多线程环境;实现懒加载效果;

  1. 1.过程:
  2. a.构造器私有化;
  3. b.类的内部声明私有静态对象并用volatile修饰
  4. c.向外暴露静态公共方法,对象为空时,同步代码块只包含创建对象语句并且再次判空,返回对象实例
class A{ 
private final static volatile A ins; 
private A(){}; 
public static A getInstance(){
    if(ins==null){ 
        synchronized(A.class) {
            if(ins == null) {ins = new A();}
        }
        return ins;
    }}
}

2.缺点:无。实际开发推荐使用


静态内部类:外部类装载时,不会导致静态内部类装载;getInstance方法调用时才开始装载内部类且只装载一次;静态属性只会在第一次加载类时初始化,类的初始化本身也是线程安全的:

  1. a.构造器私有化;
  2. b.内部类的内部创建私有final静态外部类对象
  3. c.外部类向外暴露静态synchronized公共方法,返回内部类对象实例
class A{  private A(){};

    class B{ private final static A INS= new A();}

public static synchronized A getInstance(){return B.INS;}

}

2.缺点:无,推荐使用。


枚举类:实现单例,避免多线程问题,防止反序列化重新创建对象

 1.过程:

  1. a.新建Enum类,且只声明一个对象属性;
  2. Enum A{ INSTANCE}
  3. b. 调用 A.INSTANCE 获取单例

2.缺点:无推荐使用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值