@frank-shaw
2015-10-29T10:35:34.000000Z
字数 1276
阅读 1907
java.基础知识
单例设计模式指的是某个类只能被实例化一次,用来表示全局或系统范围的组件。单例模式常用于日记记录、工厂、窗口管理器和平台组件管理等。
1.不允许其他程序用new创建该类对象。
2.在该类创建一个本类实例。
3.对外提供一个方法让其他程序可以获取该对象。
1.私有化该类构造函数。
2.通过new在本类中创建一个本类对象。
3.定义一个公有的方法,将创建的对象返回。
单例的实现有饿汉式、懒汉式两种。具体请看代码实现:
所谓饿汉饿汉,就是担心饿死了,在一开始就准备好实例化对象,生怕以后就再也吃不到了。
class Single{
//饿汉,在一开始就已经创建了实例化对象,等待调用即可
private static Single s1 = new Single();
//私有化初始化函数,让其他函数无法调用其初始化函数
private Single(){}
//暴露一个外在函数接口,允许他人通过此函数调用唯一实例
public static Single getInstance(){
return s1;
}
}
通过分析可以知道,饿汉式不存在线程安全问题,非常保险。只是很多时候不需要一开始就实例化好对象,在别人调用的时候再来实例化也不迟。
所谓懒汉,就是懒,当你需要这个对象的时候,我才来考虑初始化,并且调用这个唯一的实例给你。在考虑了线程安全的前提下,可以协程如下代码。
class Single{
private static s1 = null;
//私有化初始化函数,让其他函数无法调用其初始化函数
private Single(){}
//暴露一个外在函数接口,允许他人通过此函数调用唯一实例
public static Single getInstance(){
if(s1 == null){
//同步代码块,线程安全用
synchronized(Single.class){
if(s1 == null){
s1 = new Single();
}
}
}
return s1;
}
}
以上代码有值得学习的地方:1.加入同步代码块是为了解决线程安全问题,这无可厚非;2.加入双重判断是为了解决效率问题:当第一个线程已经实例化该对象之后,之后的线程再也不用判断同步锁。(原来如此!)
今天看了鹏哥介绍给我的java公众号,里面看到了同样的一个懒汉式的实现,不需要同步锁即可实现线程安全,它使用的是内部类静态变量的方法。请看:
class Single{
//私有化初始化函数,让其他函数无法调用其初始化函数
private Single(){}
//注意类的使用范围
private static class SingleHolder{
private static final Single s1 = new Single();
}
public static Single getInstance(){
return SingleHolder.s1;
}
}
在初次调用getInstance()方法的时候,会将内部类SingleHolder放入到方法区中,以后不会再引入相同的类,每一次都是直接调用相同的Single实例。