多线程下单例设计模式的实现

 1 package concurrent;
 2 
 3 /**
 4  * 单例设计模式与多线程 (1)立即加载与饿汉模式 (2)延迟加载与懒汉模式(3)内置静态类实现单例设计模式
 5  * (4)枚举类实现单例设计模式
 6  * 
 7  * @author foolishbird_lmy
 8  * 
 9  */
10 class SingletonA {
11     // 立即加载与饿汉模式
12     private static SingletonA sa = new SingletonA();
13 
14     private SingletonA() {
15 
16     }
17 
18     public static SingletonA getInstance() {
19         return sa;
20     }
21 }
22 
23 class SingletonB {
24     // 延迟加载与懒汉模式,双检查模式
25     private static SingletonB sb;
26 
27     private SingletonB() {
28 
29     }
30 
31     public static SingletonB getInstance() {
32         // 延迟加载
33         if (sb == null) {
34             synchronized (SingletonB.class) {
35                 if (sb == null) {
36                     sb = new SingletonB();
37                 }
38             }
39         }
40         return sb;
41     }
42 }
43 
44 class SingletonC {
45     //内部类
46     private static class SingletonHandler{
47         private static SingletonC sc = new SingletonC(); 
48     }
49     
50     private SingletonC(){
51         
52     }
53     
54     public static SingletonC getInstance(){
55         return SingletonHandler.sc;
56     }
57 }
58 
59 enum SingletonD{
60     //使用enum枚举类实现单例模式
61     INSTANCE;
62     public void get(){
63         System.out.println();
64     }
65 }
66 class SingletonThread extends Thread {
67     public void run() {
68         System.out.println(SingletonA.getInstance().hashCode());
69         System.out.println(SingletonB.getInstance().hashCode());
70         System.out.println(SingletonC.getInstance().hashCode());
71         System.out.println(SingletonD.INSTANCE.hashCode());
72     }
73 }
74 
75 public class TestSingleton {
76     public static void main(String[] args) {
77         SingletonThread st1 = new SingletonThread();
78         SingletonThread st2 = new SingletonThread();
79         SingletonThread st3 = new SingletonThread();
80         st1.start();
81         st2.start();
82         st3.start();
83     }
84 }

1、恶汉:因为加载类的时候就创建实例,所以线程安全(多个ClassLoader存在时例外)。缺点是不能延时加载。
2、懒汉:需要加锁才能实现多线程同步,但是效率会降低。优点是延时加载。
3、双重校验锁:麻烦,在当前Java内存模型中不一定都管用,某些平台和编译器甚至是错误的,因为sb = new SingletonB()这种代码在不同编译器上的行为和实现方式不可预知。
4、静态内部类:延迟加载,减少内存开销。因为用到的时候才加载,避免了静态field在单例类加载时即进入到堆内存的permanent代而永远得不到回收的缺点(大多数垃圾回收算法是这样)。
5、枚举:很好,不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

posted @ 2016-05-13 16:40  CfoolishbirdC  阅读(321)  评论(0编辑  收藏  举报