单例模式有一下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

根据上面单利的特点,编写一个单利模式其实很简单:

饿汉:

   

 1 package single.method;
 2 /**
 3  * 饿汉
 4  * @author zengrong
 5  *
 6  */
 7 public class eSingle {
 8     /**
 9      * 在这个类被加载时,静态变量single会被初始化,
10      * 此时类的私有构造子会被调用。这时候,单例类的唯一实例就被创建出来了。
11      */
12     private static eSingle single =new eSingle();
13     /**
14      * 私有化构造函数
15      */
16     private eSingle(){}
17     /**
18      * 对外界唯一的公开生成实例的方法
19      * @return
20      */
21     public eSingle getInESingle() {
22         return single;
23
24     }
25
26
27
28
29 }

饿汉式和他的名字一样:类一加载就生成实例:

饿汉式是典型的空间换时间,当类装载的时候就会创建类的实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断,节省了运行时间。

懒汉:(线程不安全模式)

package single.method;
/**
* 懒汉式(线程不安全)
* @author zengrong
*
*/
public class lSingle {

private static lSingle single=null;

private lSingle(){}

/**
*类加载时候并不生成实例,当调用时候才去加载生成实例
* @return
*/
public static lSingle getLSingle() {
return single==null ?new lSingle():single;
}
}

 

懒汉式:时间换取空间,在类加载时候并不加载生成实例,但是在多线程情况下,二个线程几乎同时到达getLSingle()方法,这样就会产生了多个实例,违背了我们当初的想法。

解决办法,双重加锁:

 1 package single.method;
 2 /**
 3  * 改造懒汉模式变成线程安全
 4  * @author zengrong
 5  *
 6  */
 7 public class lSingleSafety {
 8     /**
 9      * 用volatile修饰的变量,
10      * 线程在每次使用变量的时候,
11      * 都会读取变量修改后的最的值。
12      * volatile很容易被误用,用来进行原子性操作。
13      */
14     private volatile static lSingleSafety singleSafety=null;
15
16
17     private lSingleSafety(){}
18     /**
19      * 采用的是双重加锁进行效率和安全
20      * @return
21      */
22     public static lSingleSafety getLSingleSafety() {
23
24         if(singleSafety==null){
25             synchronized (lSingleSafety.class) {
26                  if(singleSafety == null){
27                      singleSafety= new lSingleSafety();
28                  }
29             }
30         }
31         return singleSafety;
32     }
33
34 }

所谓“双重检查加锁”机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块,这是第一重检查,进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。

  “双重检查加锁”机制的实现会使用关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。

  注意:在java1.4及以前版本中,很多JVM对于volatile关键字的实现的问题,会导致“双重检查加锁”的失败,因此“双重检查加锁”机制只只能用在java5及以上的版本。

在多线程开发中,为了解决并发问题,主要是通过使用synchronized来加互斥锁进行同步控制。但是在某些情况中,JVM已经隐含地为您执行了同步,这些情况下就不用自己再来进行同步控制了。这些情况包括:

  1.由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时

  2.访问final字段时

  3.在创建线程之前创建对象时

  4.线程可以看见它将要处理的对象时

  • 类级内部类?

  简单点说,类级内部类指的是,有static修饰的成员式内部类。如果没有static修饰的成员式内部类被称为对象级内部类。

  类级内部类相当于其外部类的static成分,它的对象与外部类对象间不存在依赖关系,因此可直接创建。而对象级内部类的实例,是绑定在外部对象实例中的。

  类级内部类中,可以定义静态的方法。在静态方法中只能够引用外部类中的静态成员方法或者成员变量。

  类级内部类相当于其外部类的成员,只有在第一次被使用的时候才被会装载。

根据上面的这些:

那么我们是不是可以在创建一个线程安全且又不用同步锁:

 1 package single.method;
 2 /**
 3  * 使用类级别的静态类部类来进行实例化
 4  * @author zengrong
 5  *
 6  */
 7 public class StaticSingle {
 8
 9     private StaticSingle(){}
10
11     private static class SingleOnInside{
12         /**
13          * 初始化静态
14          */
15     private static StaticSingle single=new StaticSingle();
16
17     }
18
19     /**
20      * 安全问题由JVM来保证
21      * @return
22      */
23     public static StaticSingle getStaticSingle() {
24
25         return SingleOnInside.single;
26     }
27
28 }

最牛逼的方法:高效,安全

枚举:

package single.method;
/*** 枚举方法* @author zengrong**/
public enum Singleton {/*** 定义一个枚举的元素,它就代表了Singleton的一个实例。*/uniqueInstance;/*** 单例可以有自己的操作*/public void singletonOperation(){//功能处理
    }}

单例模式的应用场景:

其中有些我也没用过,从其他博客看到的,记录下:

1. Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~

2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

3. 网站的计数器,一般也是采用单例模式实现,否则难以同步。

4. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

5. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

6. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。

7. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

8. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。

9. HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.

放在JavaWeb里讲,对于一个web项目,servletContext这个上下文对象就是单例模式的体现,因为它对应着配置文件,是全局所共享的,jsp的内置对象application也是这个道理。

对于枚举的单利模式明天继续详细分析;睡觉睡觉。。。。。

转载于:https://www.cnblogs.com/java-synchronized/p/6671303.html

4.设计模式---单例模式(上)相关推荐

  1. 技术图文:03 结构型设计模式(上)

    结构型设计模式(上) 本教程主要介绍一系列用于如何将现有类或对象组合在一起形成更加强大结构的经验总结. 知识结构: 享元模式 – 实现对象的复用 Sunny 软件公司欲开发一个围棋软件,其界面效果如下 ...

  2. Python设计模式-单例模式

    Python设计模式-单例模式 基于Python3.5.2,代码如下 #coding:utf-8 import threading import timeclass Singleton(object) ...

  3. Go 语言实现 23 种设计模式 单例模式

    Go 语言实现 23 种设计模式 单例模式 单例模式 单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例.使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管 ...

  4. 炒冷饭系列:设计模式 单例模式

    2019独角兽企业重金招聘Python工程师标准>>> 炒冷饭系列:设计模式 单例模式 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆 ...

  5. 软件设计模式“单例模式”和“工厂模式”

    软件设计模式"单例模式"和"工厂模式" 单例模式 什么是单例模式 单例模式的实现方式有哪些 单例模式的优缺点 单例模式的应用场景 总结 工厂模式 什么是工厂模式 ...

  6. Java 设计模式 - 单例模式

    Java 设计模式 - 单例模式 作者: 霍英俊 [huo920@live.com] 文章目录 Java 设计模式 - 单例模式 单例设计模式介绍 单例设计模式八种方式 饿汉式 - 静态常量 饿汉式( ...

  7. 厚积薄发打卡Day75 :【MSUP】Java语言特性与设计模式(上)

    前言 在看狂神频道的时候偶然发现下图,感触颇深.特别在当今[程序 = 业务 + 框架]思想盛行的开发者中,夯实基础基础显得格外重要,因此开此专栏总结记录. 设计模式详解 设计模式的考察点,一般有2个: ...

  8. 被说了很多遍的设计模式---单例模式

    [把你的理性思维慢慢变成条件反射] 本文,我们讲介绍单例模式,文章主题结构与上文一致.惯例,先来看看我们示例工程的环境: 操作系统:win7 x64 其他软件:eclipse mars,jdk8 -- ...

  9. 设计模式——单例模式、工厂模式

    设计模式--单例模式.工厂模式 一.六大设计原则 开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭.在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热 ...

  10. 软件设计师——设计模式笔记上

    软件设计师--设计模式笔记上(创造型5种) 设计模式的主要目的 设计模式的原则 1.工厂方法模式(类模式) 意图 适用性 代码实现 2.抽象工厂模式(对象模式) 意图 适用性 代码实现 3.生成器模式 ...

最新文章

  1. Hadoop Backup Node
  2. DNS服务器全面解析--转
  3. [EF4] CompiledQuery预编译性能提升 + 数据载入之大彻大悟
  4. git push时报错fatal: Could not read from remote repository.
  5. 计算机主板过热报警,利用电脑主板BIOS的报警声音辨别电脑故障
  6. HIT 软件构造 软件维护 设计原则
  7. 50个认知偏误:Elon Musk thinks everyone should know about
  8. 公平的错觉:韩国教育辛酸史
  9. html中快速复制上一行并粘贴到下一行
  10. 嵌入式岗位Makefile常见面试题(1)
  11. 3.3KW车载充电机开关电源方案数字控制单相PFC与全桥LLC
  12. 某些排序问题中元素大小比较的化简以及传递性证明
  13. 在哪里计算机的cpu显卡硬盘,电脑硬件升级攻略 CPU/内存/显卡/固态硬盘该如何选择?...
  14. 普通管理类程序开发之难度系数、层次之说法
  15. Ambari入门及安装
  16. android代码编写,如何正确编写Android代码
  17. ISV的想法,用友全都懂
  18. 【项目实战】基于Python的校园二手交易网站Django二手商城系统
  19. 在Linux 里使用IE的方法 - IEs4Linux
  20. 谷歌Android开源串口通信使用

热门文章

  1. SLF4J: Class path contains multiple SLF4J bindings.
  2. SQL Server 变量名称的Collcation跟Instance还是跟当前DB?
  3. 浅谈网站内容应该做给谁看?
  4. 计算机辅助开始于计算机发展的第几个阶段,计算机辅助开始于计算机发展第几阶段...
  5. excel取整函数_查询函数Choose、Lookup、Hlookup、Vlookup应用技巧解读
  6. PostgreSQL 12系统表(7)pg_sequence
  7. 4怎样判断动作是否执行_汽车驾驶怎样试验高压火,怎样判断分电器盖是否破裂,来看看吧!...
  8. windows下的工具链 树莓派_Windows下交叉编译Qt 5.14.2至树莓派平台 QEMU模拟树莓派...
  9. 宝德服务器硬盘报警,宝德“超人”系列PR4880G
  10. php购物网站类的继承和多态,类的继承与多态