设计模式一 单例模式

单例模式是一个很常用的创造型模式,其主要目的是控制生成对象的唯一性。在java中实例化对象的方法主要通过new(还有反射、clone等,本篇不讨论)。为了限制new方法的使用,首先要将单例类的构造函数设置为private,如此客户端就无法直接调用构造函数来new对象了。
下图是单例模式的一个简单类图:
[img]http://dl2.iteye.com/upload/attachment/0114/6366/0ba73bd1-d498-3c95-80f6-adfd3fbfdc63.png[/img]
通过静态方法getInstance获取对象实例,一种方式是通过static初始化模块来实例化这个单例对象,这种方式在该类被加载时实例,由于类的初始化过程是唯一的所以这种单例模式也是线程安全的。

public class OneClass {
private static OneClass instance=new OneClass();
private OneClass(){

}
public static OneClass getInstance(){
return instance;
}
public void func(){
System.out.println(this.toString());
}

public static void main(String args[]){
OneClass one=OneClass.getInstance();
one.func();
}
}

另外一种方式在第一次获取getInsatnce时进行实例化,这种方式明显在多线程情况下需要对getInstance进行加锁控制。下面这段代码是未对getInstance进行加锁,由于构造函数的2秒暂停,可以发现最终结果子线程和main线程打印出的对象id是不同的。解决的方法很简单对getInstance方法添加synchronized关键字即可。

public class OneClass {
private static OneClass instance=null;
private OneClass(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static OneClass getInstance(){
if(instance==null){
instance=new OneClass();
}
return instance;
}
public void func(){
System.out.println(this.toString());
}

public static void main(String args[]){
new Thread(new Runnable(){
public void run() {
OneClass two=OneClass.getInstance();
two.func();
}
}).start();;
OneClass one=OneClass.getInstance();
one.func();
}
}


当然也可以将锁移动到内部具体实例化的代码段,来缩小加锁区域,其中需要额外注意的是在获取到锁之后需要再次判断下instance引用是否为空(因为线程获得到锁之后会继续执行下去):

public static OneClass getInstance(){
if(instance==null){
synchronized(OneClass.class){
if(instance==null){
instance=new OneClass();
}
}
}
return instance;
}

最后给出一种最简洁的写法,通过内部类来获取单例,由于内部类在调用getInstance的时候才会被初始化,因此达到懒汉模式:

public class OneClassBest {
private OneClassBest(){
}
private static class ClassHandle{
private static OneClassBest oneInstace=new OneClassBest();
}
public static OneClassBest getInstance(){
return ClassHandle.oneInstace;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值