JAVA设计模式之单例设计模式

Wesley13
• 阅读 808

        单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

  在JAVA中实现单例,必须了解JAVA内存机制,JAVA中实例对象存在于堆内存中,若要实现单例,必须满足两个条件:

  1.限制类实例化对象。即只能产生一个对象。

  2.保证外部能够获取这个对象,否则对象创建将毫无意义

  如要满足以上两个条件,可以将构造方法私有化,然后在类中提供一个静态方法获取类实例。代码如下

 1 public class SingleTon {
 2 
 3     private static final SingleTon single = new SingleTon();  
 4 
 5     private SingleTon() {
 6 
 7     }
 8 
 9     /**
10      * 获取一个单例对象。
11      * @return 返回SingleTon对象。
12      */
13     public static SingleTon getInstance() {
14         return single;
15     }
16 
17 }

  JVM加载SingleTon后,会对静态成员做默认初始化,此时new SingleTon()创建的对象会赋值给single,类只会被加载一次,即使多次调用getInstance方法,所返回的对象也不会改变。single字段在初始化的过程中,对象就创建了,所以以上案例的代码又称为饿汉式。从对象的生命周期来看,类一旦加载,对象会在堆中立即创建,会浪费内存空间,因此,又存在另外一种称为懒汉式的单例设计模式。代码如下:

 1 public class SingleTonLazy {
 2 
 3     private static SingleTonLazy single = null;
 4 
 5     private SingleTonLazy() {
 6 
 7     }
 8 
 9     /**
10      * 获取一个单例对象。
11      * @return 返回SingleTon对象。
12      */
13     public static SingleTonLazy getInstance() {
14 
15         if (single == null) {
16             single = new SingleTonLazy();
17         }
18   
19         return single;
20 
21     }
22 
23 }

  SingleTonLazy在被加载进方法区后,不会立即创建对象,而是直到getInstance方法被调用以后,对象才会被创建。这种方式可以节约内存空间,但是也存在着线程安全问题,当线程A执行到判断对象为null,此时线程B获得执行权,线程B判断对象为null,此时线程A重新获得执行权,创建对象,线程B恢复,继续创建对象。将代码修改如下,使用同步锁解决线程安全问题。

 1 public class SingleTonLazy {
 2 
 3     private static SingleTonLazy single = null;
 4 
 5     private final static Lock lock = new ReentrantLock();
 6 
 7     private SingleTonLazy() {
 8 
 9     }
10 
11     /**
12      * 获取一个单例对象。
13      * @return 返回SingleTon对象。
14      */
15     public static SingleTonLazy getInstance() {
16 
17         if (single != null) {
18             return single;
19         }
20 
21         lock.lock();
22         if (single == null) {
23             single = new SingleTonLazy();
24         }
25         lock.unlock();
26 
27         return single;
28 
29     }
30 }

  总结:饿汉式与懒汉式各有优缺点,但是相对来说,占用内存空间比让cpu判断锁的开销要小,所以饿汉式更使用一些。

点赞
收藏
评论区
推荐文章
3A网络 3A网络
2年前
Golang 常见设计模式之单例模式
之前我们已经看过了Golang常见设计模式中的装饰和选项模式,今天要看的是Golang设计模式里最简单的单例模式。单例模式的作用是确保无论对象被实例化多少次,全局都只有一个实例存在。根据这一特性,我们可以将其应用到全局唯一性配置、数据库连接对象、文件访问对象等。Go语言实现单例模式的方法有很多种,下面我们就一起来看一下。饿汉式饿汉式实现单例模式非
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java设计模式1
1:单例模式简介  单例模式是一种常用的软件设计模式,它确保某个类只有一个实例,而且自行实例化并向整个系统提供唯一的实例。总而言之就是在系统中只会存在一个对象,其中的数据是共享的  特点:    单例类只能有一个实例,所以一般会用static进行修释。    单例类必须自己创建自己的唯一实例。也就是在类中要new一个自己。    单例类必
Wesley13 Wesley13
3年前
java 23种设计模式(五、单例模式)
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。单例模式的结构  单例模式的特点:单例类只能有一个实例。单例类必须自己创建自己的唯一实例。单例类必须给所有其他对象提供这一实例。  饿汉式单例类publicclassEagerSingleton
红烧土豆泥 红烧土豆泥
3年前
创建型模式之单例设计模式
什么是单例设计模式?顾名思义,只有一个实例。单例模式它主要是确保一个类只有一个实例,并且可以提供一个全局的访问点。废话少说,直接上干货了单例模式之饿汉式所谓饿汉式,顾名思义,“它很饿”。所以说,它一旦被加载进来,就会直接实例化一个对象。例如:languageclassSingleton{privatestaticfin
Wesley13 Wesley13
3年前
Java单例模式
什么是单例模式  单例模式是在程序中,一个类保证只有一个实例,并提供统一的访问入口。为什么要用单例模式节省内存节省计算如对象实例中的一样的,那就不用每次都创建一个对象方便管理因为单例提供一个统一的访问入口,不需要创建N多个对象,很多工具类都用了单例实现,如日志、字符串工具类
Wesley13 Wesley13
3年前
PHP单例模式(精讲)
首先我们要明确单例模式这个概念,那么什么是单例模式呢?单例模式顾名思义,就是只有一个实例。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类我们称之为单例类。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例
Stella981 Stella981
3年前
C#设计模式(1)——单例模式(Singleton)
单例模式即所谓的一个类只能有一个实例,也就是类只能在内部实例一次,然后提供这一实例,外部无法对此类实例化。单例模式的特点:1、只能有一个实例;2、只能自己创建自己的唯一实例;3、必须给所有其他的对象提供这一实例。普通单例模式(没有考虑线程安全)  ///<summary///单例模式
Wesley13 Wesley13
3年前
(面试常问)4种单例设计模式的总结(内含代码以及分析)
单例设计模式:  单例模式,是一种常见的软件设计模式.在它的核心结构中只包含了一个被称为单例的特殊类.通过单例模式可以保证系统中只有该类的一个实例对象.优点:  实例控制:单例模式会阻止其它对象实例化其自己的单例对象的副本,从而确保所有对象都访问的是唯一的实例   灵活性:因为类控制了实例化过程,所以类可以很灵活的更改实
Wesley13 Wesley13
3年前
23种设计模式(1):单例模式
定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。类型:创建类模式类图:!23种设计模式(1):单例模式第1张|快课网(http://static.oschina.net/uploads/img/201407/05200605_0dij.gif"23种设计模式(1):单例模式