标签:
在程序设计中,对于有的类只需要创建一个对象时,我们就会采用单例模式.
这里首先给出一个经典的单例模式的例子:
1 public class Singleton { 2 private static Singleton uniqueInstance; 3 private Singleton(){ 4 } 5 public static Singleton getInstance(){ 6 7 if (uniqueInstance==null) { 8 uniqueInstance = new Singleton(); 9 } 10 return uniqueInstance; 11 } 12 }
但改代码会出现一个问题,在多线程运行的情况下可能出现错误,例如出现创建出两个对象的情况.
所以下边着重介绍如何消除多线程情况下的错误问题
给出三种解决方法:
1.采用synchronized关键字
public class Singleton1 { private static Singleton1 uniqueInstance; private Singleton1(){ } public static synchronized Singleton1 getInstance(){ if(uniqueInstance==null){ uniqueInstance=new Singleton1(); } return uniqueInstance; } }
该种方法能保证多线程时安全运行,但其缺点也很明显:在运行时效率太低
创建好对象,之后运行该函数再采用线程保护完全是一种浪费.
可以在运行频率不高的时候采用
2.采用急切的方式创建
private static Singleton2 uniqueInstence= new Singleton2(); private Singleton2(){ } public static Singleton2 getInstance(){ return uniqueInstence; } }
在将类加载进jvm时就生成对象,这样做避免了多线程的问题,但是也带来了新的问题,
试想如果大量的类都在加载时创建,会造成大量的资源浪.
3.采用双重检查加锁机制
public class Singleton3 { private volatile static Singleton3 uniqueInstance; private Singleton3(){ } public static Singleton3 getInstance(){ if(uniqueInstance==null){ synchronized (Singleton3.class) { if (uniqueInstance==null) { uniqueInstance=new Singleton3(); } } } return uniqueInstance; } }
这种方法是比较推荐的方法,既可以提高性能,又不造成资源浪费,
但此种方法在java5之前的版本不适用
标签:
原文地址:http://www.cnblogs.com/wentjiang/p/4475096.html