单子模式,顾名思义,就是在整个应用过程中只向外界提供唯一的一份实例。很多时候我们有这样的需求,譬如当我们在计算机上多次点击打开回收站或者某个PPT时,实际只会在我们面前呈现一个窗口。
      许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。再比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。这就是单子模式的用。
-----------------------------------------------------------------------------------------------
      单子模式的JAVA实现有两种形式:饿汉模式+懒汉模式
      实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
      单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。
-----------------------------------------------------------------------------------------------
两种不同实现方式的区别:
<1> 从资源利用的角度看,懒汉式是在调用其静态方法的时候才被实例化的,所以要比饿汉式稍好一些。
<2> 从反映时间和速度上看,饿汉式在类加载的时候就得到了初始化,所以要比懒汉式好一些。
由上可见,创建一个单子类必须满足以下三个条件:
1.构造器私有
2.自己持有自身的一个静态引用
3.对外面系统提供访问唯一实例的公共静态接口(方法).
具体了解还是看程序吧,(*^__^*) 嘻嘻……:
//饿汉实例
public class Singleton2    {
  //私有的静态的的属性①
  private static Singleton2 instance;
  //构造器私有②
  private Singleton2() {
    }
  //公共的静态的方法③
  public static Singleton2 getInstance() {
    if(instance == null) {
      System.out.println("instance is null");
      instance = new Singleton2();        
    }    
    System.out.println("instance is null");
    return instance;
    }
}
//测试类
class TestSingleton {
  public static void main(String[] args) {
    Singleton2 s1 = Singleton2.getInstance();
    Singleton2 s2 = Singleton2.getInstance();
    System.out.println(s1 == s2);
  }//
}
//懒汉实例
public class Singleton1    {
  //私有的静态的的属性①
  private static Singleton1 instance;
  //构造器私有②
  private Singleton1() {
    }
  //公共的静态的方法③
  public static Singleton1 getInstance() {
      return instance;
  }
}
//测试类
class TestSingleton {
  public static void main(String[] args) {
    Singleton1 s1 = Singleton1.getInstance();
    Singleton1 s2 = Singleton1.getInstance();
    System.out.println(s1 == s2);
  }//
}