单例模式(Singleton):当系统中只需要的某个类的唯一对象时,可以使用该模式。 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

为什么会用到该模式?因为有时候某些对象的创建需要耗费大量的资源、使用单一(唯一)的对象实例来维护某些共享数据等,在这些场景下即可采用单例模式进行设计,可以适当地渐少内存开销,因为此时该唯一对象不会(被限制了)频繁地创建。

一个简单单例类图如下:

代码实现如下:

单例类Singleton01

 

class Singleton01 {
   private static Singleton01 singleton = null;
   // 私有的构造函数,限制外部环境的非法创建和访问
   private Singleton01() {
     //一些初始化操作
  }
   // 静态方法,用于创建单例类的“唯一”实例
   public static Singleton01 getInstance() {
     if (singleton == null) {
      singleton = new Singleton01();
    }
     return singleton;
  }
   // 单例类也需要提供其他静态方法给外部环境访问,完成一定的服务
   public void doSomethings() {
    System.out.println( "do somethings ...");
  }
}
客户端类Client
public class Client {
   public static void main(String[] args) {
    Singleton01 s1 = Singleton01.getInstance();
    Singleton01 s2 = Singleton01.getInstance();
    Singleton01 s3 = Singleton01.getInstance();

    System.out.println( "s1 == s2 : " + (s1 == s2));
    System.out.println( "s1 == s3 : " + (s1 == s3));
    System.out.println( "s2 == s3 : " + (s2 == s3));
  }
}
注意:如此设计的单例类并不是线程安全的,原因大家都明白,在getInstance()方法中的条件判断并不是原子性的,当多个线程同时访问时则可能出现混乱,所以我们可以在该方法前加上synchronized关键字来保证其被同步访问。但是,学过OS进程同步知识的我们知道,此时的同步还不是很严格的,我记得是需要两个条件判断来实现的,具体的优化实现请参考具体的教材。

其实,如果真正地只想某个类仅仅拥有一个唯一的实例,使用下面这种“饿汉式”的实现更加合理些,请详看其中的不同之处 。

“饿汉式” Singleton02 类:

class Singleton02 {
   // 直接为该单例类创建一个实例对象
   private final static Singleton02 singleton = new Singleton02();
   private Singleton02() {
     //一些初始化操作
  }
   // 直接返回唯一的单例对象
   public static Singleton02 getInstance() {
     return singleton;
  }
   public void doSomethings() {
    System.out.println( "do somethings ...");
  }
}
另外,有时我们并不仅仅满足于一个唯一的实例对象,而是需要为数不多但是又不能超过一定数量的实例对象,此时可以用一个容器来预先创建并装载一定数量的实例,在提供一个外部接口供外部访问获得其中一个实例。

此时的类图如下:
代码实现如下:

Singleton03 类:

 

class Singleton03 {
   private final static int MAX_NUM_OF_INSTANCE = 3;
   private static List<Singleton03> singletonList = new ArrayList<Singleton03>();
     //以静态代码块的方式来初始化一定数量的单例对象
   static {
     for( int i = 0; i < MAX_NUM_OF_INSTANCE; i++) {
      singletonList.add( new Singleton03());
    }
  }
     public static Singleton03 getInstance() {
     //从单例类已持有的实例中随机取出一个实例
    Random random = new Random();
     int id = random.nextInt(MAX_NUM_OF_INSTANCE);
     return singletonList.get(id);
  }
     private Singleton03() {
     //一些初始化操作
  }
     public void doSomethings() {
    System.out.println( "do somethings ...");    
  }
}
以上是我学习参考了秦小波的《设计模式之禅》中的单例模式以及其他之前看过的相关书籍之后,结合自己的理解和总结得出的,希望以此来巩固学过的知识,更希望能与正在学习中的大家互相学习共同进步!