Singleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在.再举个例子,集合中的 set 中不能包含重复的元素,添加到set里的对象必须是唯一的,如果重复的值添加到 set,它只接受一个实例.JDK中正式运用了Singleton模式来实现 set 的这一特性,大家可以查看java.util.Collections里的内部静态类SingletonSet的原代码.其实Singleton是最简单但也是应用最广泛的模式之一
用静态方法实现 Singleton 这种方法是使用静态方法来监视实例的创建.为了防止创建一个以上的实例,我们最好把构造器声明为 private.这样可以防止客户程序员通过除由我们提供的方法之外的任意方式来创建一个实例,如果不把构造器声明为private,编译器就会自作聪明的自动同步一个默认的friendly构造器.这种实现方法是最常见的.
public class Singleton {
private static Singleton s;
private Singleton(){};
/**
* Class method to access the singleton instance of the class.
*/
public static Singleton getInstance() {
if (s == null)
s = new Singleton();
return s;
}
}
// 测试类
class singletonTest {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1==s2)
System.out.println("s1 is the same instance with s2");
else
System.out.println("s1 is not the same instance with s2");
}
}
缺点:方法线程不安全,需要在方法上加同步,但会影响效率。
另外一种:
-
- public class c{
- private static Singleton s=new Singleton();
- private Singleton(){};
- public static Singleton getInstance() {
- return s;
- }
- }
这种方法得保证加载器是一个private Singleton(){};
JVM加载类不会产生线程安全问题,即两个线程同时去加载这个类,也会按顺序加载,所以不会产生线程安全问题
缺点:不是lazy,每次都会新建一个Singleton,不管有没有用到
第三种,即是lazy的,又满足单实例:
- public class Singleton {
- private static class SingletonHolder {
- final static Singleton INSTANCE = new Singleton();
- }
-
- private Singleton (){
- }
-
- public Singleton getInstance() {
- return SingletonHolder.INSTANCE;
- }
- }