之前刚进公司的时候,看到公司工作一年多的同事 写了一个 统计 系统在线登陆人数的功能,当时他跟我说是用单例实现的。就一直想弄明白单例是怎么回事。这几天又重新 调试 看资料 更清楚的大概明白了单例模式。
所谓单例模式,简单来说,就是在整个应用(举例:办公OA这样的应用)中有某个类 保证只这个类只有一个实例存在。就像是Java Web中的application,也就是提供了一个全局变量,用处相当广泛,比如保存全局数据(统计登陆系统人数),实现全局性的操作等
最简单的 最常用的实现就是
public class SingletonClass {
private static final SingletonClass instance = new SingletonClass();
public static SingletonClass getInstance() {
return instance;
}
private SingletonClass() {
}
}
首先 把类的构造方法 用private 修饰,这样就可以防止在类外实例化该类(在该类外 new该类的对象 无法实现)。只提供一个静态的getInstance()方法可以返回实例给使用者。
外部使用者如果需要使用SingletonClass的实例,只能通过getInstance()方法,这样就保证了此类只能有一个实例存在。
这是最简单的单例使用方法(被称为 饿汉模式),同时也不存在多线程安全的问题。
之前从网上看的说这种 把构造方法设成private的 ,如果用反射方法
Class.forName(name).newInstance()
实例化对象 就会使单例失效(类的实例不止一个对象)
但是 我自己做的test 却是 后台报错 无法实例化 private 修饰构造方法的类。不知道是怎么回事。在这求大家讨论。
关于该实现的线程安全解释:
此实现是线程安全的,当多个线程同时去访问该类的getInstance()方法时,不会初始化多个不同的对象,这是因为,JVM(Java Virtual Machine)在加载此类时,对于static属性的初始化只能由一个线程执行且仅一次 。
此饿汉模式的唯一一个缺点就是 无论这个类是否被使用,类加载的时候都会创建一个instance对象。如果这个创建过程很耗时,并且这个类还并不一定会被使用,那么这个创建过程就是无用的。
但是 我觉得一般在工作中,不用此类的单例,干嘛要写成这样的呢(写到即会用到)。所以觉得这是很好的在java里面实现单例的方法。
当然解决这个缺点的方式有一个是叫 懒汉模式的实现方法:
public class SingletonClass { private static SingletonClass instance = null;
public static SingletonClass getInstance() {
if(instance == null)
{ instance = new SingletonClass();
}
return instance; }
private SingletonClass() { }
}
这个实现方式 牵扯到线程安全的问题这个想等我自己真正用到了 或者理解了 在发出来 和大家讨论。