单例模式可保证一个类只有一个实例,并提供一个类方法来访问该实例。
class SingletonDemo
{
private static SingletonDemo singletonDemo;
//构造函数的访问权限设置为private,防止外部自己构造实例
private SingletonDemo(){}
public static SingletonDemo getInstance(){
if(singletonDemo == null){
singletonDemo = new SingletonDemo();
}
return singletonDemo;
}
}
以上方法仅适用于单线程的情景下,因为在多线程情景下,会发生创建多个类实例的情况。
如下图:
-
第一种:
class SingletonDemo1
{private static SingletonDemo1 singletonDemo1; private SingletonDemo1(){} //通过增加synchronized关键字来加锁 public static synchronized SingletonDemo1 getInstance(){ if(singletonDemo1 == null){ singletonDemo1 = new SingletonDemo1(); } return singletonDemo1; }
}
此方法的缺点:每次调用getInstance方法都要加锁,会造成很大的开销,是程序的效率大大降低,因此这不是最好的方法。
-
第二种:
class SingletonDemo2
{//急切创建实例,通过添加static关键字来使每次加载类的时候就创建实例 private static SingletonDemo2 singletonDemo2 = new SingletonDemo2(); private SingletonDemo2(){} public static SingletonDemo2 getInstance(){ return singletonDemo2; }
}
-
第三种:
class SingletonDemo3
{//通过添加volatile关键字来保证实例的同步 private volatile static SingletonDemo3 singletonDemo3; private SingletonDemo3(){} public static SingletonDemo3 getInstance(){ if(singletonDemo3 == null){ //这里二次加锁 synchronized(SingletonDemo3.class){ if(singletonDemo3 == null) singletonDemo3 = new SingletonDemo3(); } return singletonDemo3; }
}
注意:这种方法只能应用于jdk1.5及以后的版本,之前的版本是不适用的,因为之前的版本中jvm对于volatile关键字的实现会是双重加锁的失效。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。