浅析Java设计模式 - 单例模式

以下是三种单例模式的代码实现,前两者用的比较多 (言外之意 最后一种可以忽略)

  1 package com.signle;
  2
  3 import java.util.HashMap;
  4 import java.util.Map;
  5
  6 /**
  7  *
  8  * @title 单例模式
  9  * @Copyright Copyright (c)2016年3月9日
 10  * @Company CTC
 11  * @version 1.0
 12  * @author ejokovic
 13  * @time   上午11:21:53
 14  * @package
 15  * com.signle
 16  *
 17  */
 18 public class TestSignle {
 19     public static void main(String[] args) {
 20         Singleton s = Singleton.getInstance();
 21         Singleton s1 = Singleton.getInstance();
 22         //System.out.println(s==s1);
 23         SigletionC singleC = SigletionC.getInstance(null);
 24         System.out.println(singleC.about());
 25     }
 26
 27 }
 28
 29 /**
 30  * 懒汉式
 31  *  是线程不安全的并发环境下很可能出现多个Singleton实例,要实现线程安全
 32  * @title
 33  * @Copyright Copyright (c)2016年3月9日
 34  * @Company CTC
 35  * @version 1.0
 36  * @author ejokovic
 37  * @time   上午11:23:44
 38  * @package
 39  * com.signle
 40  *
 41  */
 42 class Singleton{
 43     private Singleton(){}
 44     private static Singleton Singleton;
 45     public static Singleton getInstance(){
 46         if(Singleton==null){
 47             Singleton = new Singleton();
 48         }
 49         return Singleton;
 50     }
 51 }
 52
 53 /**
 54  * 解决懒汉式单例线程安全(一)
 55  * 在getInstance方法上加同步锁
 56  * @title
 57  * @Copyright Copyright (c)2016年3月9日
 58  * @Company CTC
 59  * @version 1.0
 60  * @author ejokovic
 61  * @time   上午11:31:45
 62  * @package
 63  * com.signle
 64  *
 65  */
 66 class Singleton2{
 67     private Singleton2(){}
 68     private static Singleton2 Singleton;
 69     public static synchronized  Singleton2 getInstance(){
 70         if(Singleton==null){
 71             Singleton = new Singleton2();
 72         }
 73         return Singleton;
 74     }
 75 }
 76
 77 /**
 78  * 解决懒汉式单例线程安全(二)
 79  * 双重检查锁定
 80  * @title
 81  * @Copyright Copyright (c)2016年3月9日
 82  * @Company CTC
 83  * @version 1.0
 84  * @author ejokovic
 85  * @time   上午11:34:42
 86  * @package
 87  * com.signle
 88  *
 89  */
 90 class Singleton3{
 91     private Singleton3(){}
 92     private static Singleton3 Singleton;
 93     public static synchronized  Singleton3 getInstance(){
 94         if(Singleton==null){
 95             synchronized (Singleton3.class){
 96                 if(Singleton==null){
 97                     Singleton = new Singleton3();
 98                 }
 99             }
100         }
101         return Singleton;
102     }
103 }
104
105 /**
106  * 解决懒汉式单例线程安全(二)
107  * 静态内部类
108  * 这种比上面1、2都好一些,既实现了线程安全,又避免了同步带来的性能影响。
109  * @title
110  * @Copyright Copyright (c)2016年3月9日
111  * @Company CTC
112  * @version 1.0
113  * @author ejokovic
114  * @time   下午12:06:54
115  * @package
116  * com.signle
117  *
118  */
119 class Singleton4{
120     private static class LazyHolder{
121          private static final Singleton4 INSTANCE = new Singleton4();
122     }
123     private Singleton4(){}
124     public static synchronized  Singleton4 getInstance(){
125         return LazyHolder.INSTANCE;
126     }
127 }
128
129 /**
130  * 饿汉式单例类.在类初始化时,已经自行实例化
131  * @title
132  * @Copyright Copyright (c)2016年3月9日
133  * @Company CTC
134  * @version 1.0
135  * @author ejokovic
136  * @time   下午12:12:23
137  * @package
138  * com.signle
139  *
140  */
141 class SigletionA{
142     private SigletionA(){}
143     private static final SigletionA sigletionA = new SigletionA();
144     public static SigletionA getInstance(){
145         return sigletionA;
146     }
147 }
148
149 //登记式单例
150 class SigletionC{
151     private static Map<String,SigletionC> map = new HashMap<String,SigletionC>();
152     static{
153         SigletionC single = new SigletionC();
154         map.put(single.getClass().getName(), single);
155     }
156     //保护的默认构造子
157     protected SigletionC(){}
158     //静态工厂方法,返还此类惟一的实例
159     public static SigletionC getInstance(String name) {
160         if(name == null) {
161             name = SigletionC.class.getName();
162             System.out.println("name == null"+"--->name="+name);
163         }
164         if(map.get(name) == null) {
165             try {
166                 map.put(name, (SigletionC) Class.forName(name).newInstance());
167             } catch (InstantiationException e) {
168                 e.printStackTrace();
169             } catch (IllegalAccessException e) {
170                 e.printStackTrace();
171             } catch (ClassNotFoundException e) {
172                 e.printStackTrace();
173             }
174         }
175         return map.get(name);
176     }
177     //一个示意性的商业方法
178     public String about() {
179         return "Hello, I am RegSingleton.";
180     }
181 }

单例模式

在了解饿汉与懒汉的区别前 先了解下什么是线程安全:

假如你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时执行这段代码,如果每次执行的结果和单线程中执行的结果一致 且 其它变量的值也和预期的一致 这就是线程安全

换句话说:

一个类或者程序提供的接口对于线程来说是原子操作,或者多个线程之间切换不会导致该接口的执行结果存在差异性 也就是说我们不用考虑同步的问题 那就是线程安全的

饿汉式和懒汉式区别:

从名字上来说,饿汉和懒汉:

  饿汉是当类加载时就把单例初始化完成,保证getInstance的时候,单例是已经存在的了

  而懒汉比较懒,只有当调用getInstance的时候,才会去初始化这个单例;

从线程是否安全角度讲:

  饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题

  懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的1、2、3,这三种实现在资源加载和性能方面有些区别;

从资源加载和性能的角度讲:

    饿汉式在类加载的同时就实例化一个静态对象出来,不管之后是否用到这个静态对象,都会占据一定的内存,但是相应的 在第一次调用时的速度也会更快,因为资源已经初始化好了;

    至于以上1,2,3 这三种实现又有些区别

    第一种,在方法调用上加了同步,虽然线程安全了,但每次都要同步,会影响性能,毕竟大部分的情况下是不需要同步的

    第二种,在getInstance方法中做了两次null检查,确保了只有第一次调用该静态对象的时候才会同步,这样也是线程安全的,同时避免了每次调用时的同步损耗;

    第三种,利用了classloader机制,保证初始化instance时只有一个线程 所以是线程安全的 同时没有性能损耗

时间: 2024-10-17 14:31:50

浅析Java设计模式 - 单例模式的相关文章

浅析JAVA设计模式之工厂模式(一)

1 工厂模式简介 工厂模式的定义:简单地说,用来实例化对象,代替new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式可以动态决定将哪一个类实例化,不用先知道每次要实例化哪一个类. 工厂模式可以分一下三种形态: 简单工厂 (Simple Factory)模式:又称静态工厂模式(StaticFactory). 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory). 抽象工厂 (Abstract Factroy)模式:又称工具箱模式

浅析JAVA设计模式之工厂模式(二)

1 工厂方法模式简介 工厂方法 (Factroy Method) 模式:又称多态性工厂模式(Polymorphic Factory),在这种模式中,核心工厂不再是一个具体的类,而是一个抽象工厂,提供具体工厂实现的接口,具体创建产品交由子工厂去做,抽象工厂不涉及任何产品被实例化的细节.而不同等级的产品,就对应一个不同等级的工厂,如下图. 图1 1.1工厂方法模式(多态性工厂模式): 工厂方法模式有三个角色: 1. 抽象产品接口 2. 具体产品类 3. 抽象工厂接口 4.具体工厂类. 1.2工厂方法

浅析JAVA设计模式之工厂模式(三)

在阅读本文之前,请先阅读(一)和(二)中的简单工厂模式和工厂方法模式. 1抽象工厂模式简介 抽象工厂 (Abstract Factroy) 模式:工具箱模式(kit).抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态,如下图. 图1.1 上图左边有一个工厂类的等级结构,右边有两个不同的产品等级结构,分别是产品A的等级结构和产品B的等级结构,工厂1和工厂2分别负责不同一个产品等级,同一个产品族的产品的生产.又例如下图: 图1.2 上图表示的是Button和Text两个不同产品的等级

Java设计模式の单例模式

-------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱汉式,非线程安全 c.饱汉式,线程安全简单实现 d.线程安全 并且效率高  单例模式最优方案 3.总结 a.使用枚举的单例模式 b.使用枚举,static处调用,初始化一次 -------------------------------------------------- 1.定义 确保一个类只有

Java 设计模式 单例模式(Singleton) [ 转载 ]

Java 设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创建对象 第一种(懒汉,线程不安全): 1 public class Singleton { 2 private static Singleton instance; 3 private Singleton (){} 4 5 public static Singleton getInstan

浅析JAVA设计模式(一)

第一写技术博客,只是想把自己一天天积累的东西与大家分享.今天在看<大型网站架构和java中间件>这本书时,其中提到代理模式的动态代理.作为java中间件的一个重要基础,我觉的有必要整理和分析下java的23种设计模式,如有不对的地方,请大家留贴指正. 一.设计模式的分类 总体来说,Java的设计模式分为三个大类(创建型模式.结构型模式.行为型模式) 创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式:适配器模式.装饰模式.代理模式.外观模式(又称门面模式).桥

浅析JAVA设计模式之单例模式(一)

1 单例模式简介 单例模式确保一个类只有一个实例,并且自行实行实例化并向整个系统提供这个实例. 单例模式有三个要点: 1.某个类只能有一个实例. 2.它必须自行创建这个实例. 3.它必须向整个系统提供这个实例. 单例模式主要分为两种:饿汉式单例模式和懒汉式单例模式 1.1饿汉式单例模式: 饿汉式单例模式是java语言实现起来最为简单的单例模式,UML图如下: 图1.1 从图中可以看出,它自己将自己实例化. 1.2饿汉式单例模式的实现(建一个Singleton包,所有程序放在该包下): (1)建一

(3)Java设计模式-单例模式

单例模式(Singleton)是一种较为常用的设计模式,单例对象能保证在JVM虚拟中,该对象只有一个实例存在. 1.(懒汉,线程不安全) 1 //单例模式 2 public class Singleton { 3 // 私有化构造方法防止对象在外部被实例化 4 private Singleton() { 5 System.out.println("create"); 6 } 7 8 // 私有化静态实例,防止实例被外部应用 9 private static Singleton sing

Java设计模式-单例模式(Singleton)

单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处: 1.某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销. 2.省去了new操作符,降低了系统内存的使用频率,减轻GC压力. 3.有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了.(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程. 单例