您的位置:首页 > 其它

设计模式:单例模式

2016-03-08 10:43 316 查看
单例模式:确保一个类只有一个实例,并提供全局访问点。

通过私有化构造方法,我们可以使一个类不能在外部被实例化。

public class MyClass {
private MyClass(){
System.out.println("private MyClass()");
}
}


public class Main {
public static void main(String[] args) {
MyClass mc = new MyClass();//这里我们进行实例化的时候,编译器提示错误
}
}




实现一

public class Singleton {
private static Singleton instance;
private Singleton(){
System.out.println("private Singleton()");
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();//这里只有当我们需要的时候才会new(这就是延迟实例化,lazy instantiaze),如果不需要就会永远也不创建(这样相比全局变量而言,节约了资源),并且只会new一次。
}
return instance;
}
}


单这样实现当多线程的情况下会存在问题,如果多个线程同时
getInstance
,同时走到了
if(instance==null)
这一步,那么这几个线程都将进入if,就创建了多个对象。这是我们不能容忍的。

实现二

public class Singleton {
private static Singleton instance;
private Singleton(){
System.out.println("private Singleton()");
}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}


getInstance
方法上添加
synchronized
关键字,这样就不存在多个线程同时进入该方法了。

但是,这样同样存在一个问题,每一个进入这个方法都要同步,如果
getInstance
需要拼房的运行,这样就造成了一些性能浪费。

方法三

public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){
System.out.println("private Singleton()");
}
public static Singleton getInstance(){
return instance;
}
}


放弃延迟实例化,在JVM加载该类的时候,我们就创建唯一的实例,这样任何线程访问都没问题。

方法四(双重检查加锁)

public class Singleton {
private volatile static Singleton instance = null;
private Singleton(){
System.out.println("private Singleton()");
}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}


这样写代码,大量减少了同步带来的性能消耗,又防止了多线程带来的问题。

volatile
:用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: