单例模式

今天看了一下单例模式,收获颇丰,以前都只是马虎地学一下,现在总结一下以便以后复习。

单例模式要满足一下条件:

1)拥有私有的构造方法,确保用户无法通过new直接实例它

2)拥有静态公有方法,以确保有一个实例被创建

3)一个静态的变量用来保存单实例的引用

下面是我总结的3种方式:

1)饿汉式

 1 package com.tomwills.singleton;
 2 
 3 /**
 4  * 单例模式1--饿汉式
 5  * @author-tomwills:2013-7-22
 6  *
 7  */
 8 
 9 public class SingletonTest
10 {
11     public static void main(String[] args)
12     {
13         Singleton singleton = Singleton.getInstance();
14         Singleton singleton2 = Singleton.getInstance();
15         System.out.println(singleton == singleton2);
16         
17     }
18 }
19 class Singleton
20 {    
21     /*
22      * 一个静态的变量用来保存单实例的引用
23      * static是为了让getInstance()可以访问
24      * 静态方法只能访问静态变量
25      */
26     private static Singleton single = new Singleton();
27     
28     /*
29      * 拥有私有的构造方法,确保用户无法通过new直接实例它
30      */
31     private Singleton(){
32         
33     }
34     
35     /*
36      * 拥有静态公有方法,以确保有一个实例被创建
37      * static保证了外部类可以通过类名直接调用该方法
38      */
39     public static Singleton getInstance()
40     {
41         return single;
42     }
43 }
View Code

2)懒汉式

 1 package com.tomwills.singleton;
 2 
 3 /**
 4  * 单例模式2 懒汉式--线程安全,但效率低,
 5  * 因为很多情况下不需要线程同步
 6  * 
 7  * @author-tomwills:2013-7-22
 8  */
 9 
10 public class SingletonTest2 {
11 
12     public static void main(String[] args) {
13         Singleton2 s = Singleton2.getInstance();
14         Singleton2 s2 = Singleton2.getInstance();
15         System.out.println(s == s2);
16     }
17 }
18 
19  class Singleton2 {  
20      private static Object object = new Object();
21      private static Singleton2 instance; 
22      
23      private Singleton2 (){
24          
25      }
26      
27      /*
28       * synchronized关键字 
29       * 保证在同一时刻最多只有一个线程执行该段代码(线程安全)
30       * 
31       * synchronized代码块
32       * 只会将块中代码同步,块外的可以被多个线程访问,提高开发效率
33       * 若没有synchronized代码块,则线程不安全
34       */
35      public static Singleton2 getInstance() { 
36          synchronized(object){            
37              if (instance == null) {  
38                     instance = new Singleton2();  
39                  }  
40                      return instance;
41          }  
42      }  
43  } 
View Code

3)双重校验锁

 1 package com.tomwills.singleton;
 2 
 3 /**
 4  * 单例模式3 双重校验锁(Double-Checked Locking)
 5  * 是懒汉式的升级版
 6  * 
 7  * @author-tomwills:2013-7-22
 8  */
 9 
10 public class SingletonTest3 {
11 
12     public static void main(String[] args) {
13         Singleton3 s = Singleton3.getInstance();
14         Singleton3 s2 = Singleton3.getInstance();
15         System.out.println(s == s2);
16     }
17 }
18 
19  class Singleton3 {  
20      
21      private static Singleton3 instance; 
22      
23      private Singleton3 (){
24          
25      }
26      
27      /*
28       * 先判断实例是否为空再加锁,而不用让线程每次都加锁
29       */
30      public static Singleton3 getInstance() {             
31              if (instance == null) { 
32                  synchronized(Singleton3.class){
33                     instance = new Singleton3(); 
34                     } 
35                  }  
36                      return instance;
37          }    
38  } 
View Code

 测试结果皆为:true

 

posted on 2013-07-23 20:23  tomwills  阅读(220)  评论(0编辑  收藏  举报