-
java懒汉式与饿汉式
2020-12-17 22:09:57分为懒汉式和饿汉式 饿汉式 一开始就创建了一个对象 /** * 饿汉式 */ class EH{ private EH(){ } private static EH eh = new EH(); public static EH getEh() { return eh; } } 懒汉式 一开始不新建一...类的单例设计模式,
- 就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
- 分为懒汉式和饿汉式
饿汉式
一开始就创建了一个对象
/** * 饿汉式 */ class EH{ private EH(){ } private static EH eh = new EH(); public static EH getEh() { return eh; } }
懒汉式
一开始不新建一个对象
class LH{ private LH(){ } private static LH lh = null; public static LH getBh() { if (lh==null){ lh = new LH(); } return lh; } }
-
Java 懒汉式单例 饿汉式单例
2015-09-11 17:08:42单例模式写法一般分为两种,懒汉式和饿汉式 饿汉式 public class SingleTon { //加载类的时候会初始化static的instance,从这以后,这个static的instance对象便一直占着这段内存,永远不会被回收掉。 private ...转载请注明出处:http://blog.csdn.net/mr_liabill/article/details/48374921 来自《LiaBin的博客》
单例模式很常见,在面试中也会经常直接让你写一个单例出来
单例模式写法一般分为两种,懒汉式和饿汉式
饿汉式
public class SingleTon { //加载类的时候会初始化static的instance,从这以后,这个static的instance对象便一直占着这段内存,永远不会被回收掉。 private static SingleTon instance = new SingleTon(); //将构造函数private掉,避免直接new SingleTon() private SingleTon() { } /** * 因为是单例,所以只能通过static方法来获取实例,因此必须是static的。 * 方法实现较为简单,因为instance已经在加载类的时候被初始化好了,所以不存在多线程并发造成的问题 */ public static SingleTon getInstance() { return instance; } }
优点:不需要考虑多线程问题,因为instance是静态的,在类加载的时候就已经实例化了,同时也避免了synchronized所造成的性能问题,
缺点:
但这种方式也有点弊端,因为初始化类的时候就需要构造实例,(即便你还没有用到这个实例),因此在某些特定条件下会耗费内存。
懒汉式
方式1: 基于volatile的双重检查锁定的解决方案为什么需要按如下这么复杂的去实现,参考有详细的解释 http://blog.csdn.net/guolin_blog/article/details/8860649
这样写是没问题的,因为私有构造函数中没有初始化任何属性,否则的话上面的代码还需要改进public class SingleTon { private static SingleTon instance = null; //将构造函数private掉,避免直接new SingleTon() private SingleTon() { } //synchronized避免多线程带来的问题,但同时效率降低,另一方面采取多重锁定,提高效率 public static SingleTon getInstance() { if (null == instance) { synchronized (SingleTon.class) { if (null == instance) { instance = new SingleTon(); } } } return instance; } }
这里为什么需要使用volatile关键字呢?public class SingleTon { private static volatile SingleTon instance = null; private String name; //将构造函数private掉,避免直接new SingleTon() private SingleTon() { name = "SingleTon"; } //synchronized避免多线程带来的问题,但同时效率降低,另一方面采取多重锁定,提高效率 public static SingleTon getInstance() { if (null == instance) { synchronized (SingleTon.class) { if (null == instance) { instance = new SingleTon(); } } } return instance; } }
假设线程thread1走到了第15行的if判断发现instance==null成立,于是都进入了外部的if体。这时候thread1先获取了synchronized块的锁,于是thread1线程会执行第18行的instance = new SingleTon();这句代码,问题就出在这里,这条语句它不是原子性执行的。在Java里,实例化一个对象的过程简单地讲,可以分为两步1)先为instance对象分配一块内存,2)在这块内存里为instance对象里的成员变量赋值(比如第11行里为url赋值)。假设当thread1执行完第1)步而还没有执行第2)步的时候,另外一个线程thread2走到了第15行,这时候instance已经不是null了,于是thread2直接返回了这个instance对象。有什么问题呢?instance对象的初始化(变量赋值等操作)还没执行完呢!thread2里直接得到了一个没有初始化完全的对象,就有可能导致很严重的问题了。
那么volatile关键字有啥作用呢?当用volatile修饰了instance变量之后,对instance的写操作”先行发生“于对它的读操作。(这是Java虚拟机里的先行发生原则)这样就保证了,thread1中的instance变量被完全初始化之后,thread2才能读取它,当没有完成初始化时,thread2只能等会儿啦。优点:
需要的时候才去加载,内存消耗好一些。(因为在需要的时候才加载,所以叫懒汉式)
缺点:
代码如此复杂,,还有synchronized带来的运行效率问题,调用同步方法会慢不少
方式2: 基于类初始化的解决方案
public class Singleton { private static class SingletonHolder { public final static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }
内部类的初始化是延迟的,外部类初始化时不会初始化内部类,只有在使用的时候才会初始化内部类。而Java语言规范规定,对于每一个类或接口C,都有一个唯一的初始化锁LC与之对应。也就是说,SingletonHolder在各个线程初始化的时候是同步执行的,且全权由JVM承包了。两种延迟初始化方案总结
延迟初始化降低了初始化类或创建实例的开销,但增加了访问被延迟初始化的字段的开销。在大多数时候,正常的初始化要优于延迟初始化。如果确实需要对实例字段使用线程安全的延迟初始化,请使用上面介绍的基于volatile的延迟初始化的方案;如果确实需要对静态字段使用线程安全的延迟初始化,请使用上面介绍的基于类初始化的方案。
总结
为了省麻烦,就用恶汉式吧。但是我一般用懒汉式,比较需要的时候才加载,可以节省内存。至于synchronized引起的效率问题,基本很少有这样的场景,因为很少有两个线程并发调用getInstance方法。
-
java 懒汉式 饿汉式_Java单例模式--------懒汉式和饿汉式
2021-03-15 10:13:45下面对单件模式的懒汉式与饿汉式进行简单介绍: 1、饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。 2、懒汉式:当程序第一次访问单件模式实例时才进行创建。 如何选择:如果单件模式实例...单件模式用途:
单件模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。
单件模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。它的用途十分广泛,打个比方,我们开发了一个简单的留言板,用户的每一次留言都要将留言信息写入到数据库中,最直观的方法是没次写入都建立一个数据库的链接。这是个简单的方法,在不考虑并发的时候这也是个不错的选择。但实际上,一个网站是并发的,并且有可能是存在大量并发操作的。如果我们对每次写入都创建一个数据库连接,那么很容易的系统会出现瓶颈,系统的精力将会很多的放在维护链接上而非直接查询操作上。这显然是不可取的。
如果我们能够保证系统中自始至终只有唯一一个数据库连接对象,显然我们会节省很多内存开销和cpu利用率。这就是单件模式的用途。当然单件模式不仅仅只用于这样的情况。在《设计模式:可复用面向对象软件的基础》一书中对单件模式的适用性有如下描述:
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
下面对单件模式的懒汉式与饿汉式进行简单介绍:
1、饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。
2、懒汉式:当程序第一次访问单件模式实例时才进行创建。
如何选择:如果单件模式实例在系统中经常会被用到,饿汉式是一个不错的选择。
反之如果单件模式在系统中会很少用到或者几乎不会用到,那么懒汉式是一个不错的选择。
饿汉模式demo:
public Simple(){
private static Single a=new Single();
private Single(){
}
public static Simple getSimple(){
return s;
}
return s;
}
一般用于枚举法:
enum Single {
Single;
private Single() {
}
public void print(){
System.out.println("hello world");
}
}
public class SingleDemo {
public static void main(String[] args) {
Single a = Single.Single;
a.print();
}
懒汉模式 demo:
class Single{
private static Single s = null;
public Single() {
}
if (s == null)
s = new Single();
return s;
}
}
懒汉模式在使用时,容易引起不同步问题,所以应该创建同步"锁",demo如下
class Single1 {
private static Single1 s = null;
public Single1() {
}
//同步函数的demo
public static synchronized Single1 getInstance() {
if (s == null)
s = new Single1();
return s;
}
//同步代码快的demo加锁,安全高效
public static Single1 getInStanceBlock(){
if(s==null)
synchronized (Single1.class) {
if(s==null)
s = new Single1();
}
return s;
}
}
-
Java的单例模式懒汉式和饿汉式
2016-07-13 22:01:51懒汉式和饿汉式关于java的单例模式,懒汉式和饿汉式是较为常见的单例模式。
懒汉式是占内存空间少但是相对而言用时比较多,饿汉式是占内存空间大但是相对而言用时比较少。
其中懒汉式:
package com.qf.singleton;
public class MySingletonLanhan {
//设置静态变量
private static MySingletonLanhan mySingletonLanhan=null;
private MySingletonLanhan(){
System.out.println("懒汉式的构造方法");
}
public static MySingletonLanhan getInstance() {
if (mySingletonLanhan==null) {
System.out.println("说明没有创建~~·");
mySingletonLanhan=new MySingletonLanhan();
}
else {
System.out.println("说明已经创建了");
}
return mySingletonLanhan;
}
}饿汉式
package com.qf.singleton;
public class MySingletonEHan {
private static MySingletonEHan mySingletonEHan=new MySingletonEHan();
private MySingletonEHan(){
System.out.println("饿汉式的构造方法");
}
public static MySingletonEHan getInstance() {
System.out.println("饿汉式创建成功!!!!");
return mySingletonEHan;
}
} -
单例模式懒汉式和饿汉式区别
2018-04-11 11:19:45单例模式懒汉式和饿汉式区别 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建... -
java 饿汉式单例_java单例模式(懒汉式和饿汉式)
2021-02-12 19:46:42单例模式:简单的来说,就是为了防止你在程序中new 来new去,明明只需要一个东西,你却new了很多次,内存中存在大量没用的垃圾单例模式特点1单例类只能有一个实例。2单例类必须自己自己创建自己...这是一个和饿汉式... -
浅谈Java单例模式之懒汉式和饿汉式
2019-09-20 10:46:45浅谈Java单例模式之懒汉式和饿汉式Spring中单例和多例单例的定义单例又分为懒汉式和饿汉式功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的... -
java懒汉单例和饿汉单例_java 单例模式(饿汉模式与懒汉模式)
2021-03-13 02:57:06java 单例模式饿汉式单例对于饿汉模式,我们可这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象。懒汉式单例类对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的... -
懒汉式和饿汉式
2020-06-23 09:08:54单例模式分为懒汉式和饿汉式 懒汉式:在使用时创建对象 饿汉式:不论是否使用,都会在一开始就创建对象 区别: 饿汉式多线程安全,懒汉式多线程不安全 创建单例对象时间不同:饿汉式在使用前创建对象,懒汉式在使用 -
JAVA的懒汉式、饿汉式单例
2021-01-09 16:36:15单例模式其实是为了保证在程序运行的时候,内存中一个类只有一个实例对象,分为懒汉式和饿汉式,两者的区分方法是,是否类加载的时候就存在实例对象 package com.wy //饿汉式:在类加载的时候让其存在一个对象 ... -
java:单例懒汉与饿汉对比_java 单例模式(懒汉式与饿汉式)
2021-03-08 09:47:10单例设计模式又分为两种方式,懒汉式和饿汉式。(1)懒汉式,就是只有当调用getInstance的时候,才会初始化这个单例。(2)饿汉式,就是一旦加载好类,就把单例初始化完成。即是调用getInstance的时候,单例是已经存在了... -
java中关于懒汉式和饿汉式的个人理解
2020-03-20 09:52:32对单例模式的理解单例模式饿汉式懒汉式 单例模式 解决的问题: 如何使一个类只在内存中存在一个实例对象; 饿汉式 从线程的安全性来看,饿汉式天生是线程安全的 class Demo{ //构造函数私有化 private Demo(){ } ... -
java 饿汉式单例_java 单例模式(懒汉式与饿汉式)
2021-02-12 19:46:44单例设计模式又分为两种方式,懒汉式和饿汉式。(1)懒汉式,就是只有当调用getInstance的时候,才会初始化这个单例。(2)饿汉式,就是一旦加载好类,就把单例初始化完成。即是调用getInstance的时候,单例是已经存在了... -
【Java】单例模式中懒汉式和饿汉式对比总结
2020-03-02 17:24:04单例模式懒汉式和饿汉式区别 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及... -
JAVA 中单例设计模式之懒汉式和饿汉式
2020-07-02 15:41:17单例设计模式之懒汉式和饿汉式 单例设计模式概念 单例模式可以说是大多数开发人员在实际中使用最多的,常见的Spring默认创建的bean就是单例模式的。 单例模式有很多好处,比如可节约系统内存空间,控制资源的使用。 ... -
java学习回顾---懒汉式和饿汉式
2020-12-07 00:35:52懒汉式和饿汉式都是单例模式。单例模式其实简单来说就是把本类对外开放的构造函数私有化,不让外部随意创建本类对象,又向外提供了访问本类的方法,从而可以在该方法内增加条件,所以需要访问本必须要满足条件。 ... -
Java单例的实现(懒汉式和饿汉式)
2017-03-13 21:44:13单例作为Java23种构造方法之一,有懒汉式与饿汉式两种方式实现,以下创建了King的类,实现了相应的操作。/* 单例的实现---懒汉式 */ public class Test { public static void main(String[] args){ King king1=... -
java学习,懒汉式和饿汉式
2014-04-16 22:51:14称为:饿汉式。class Single { private static Single s=new Single();//初始化,同时对象已存在与内存 private Single(){} public static Single getInstance() { return s; }}*///对象时方法被调用... -
java中单例模式的懒汉式_Java中单例模式关于懒汉式以及饿汉式具体分析
2021-03-16 17:01:15这篇文章主要介绍了java 单例模式的相关资料,这里对懒汉式与饿汉式都做了...单例设计模式又分为两种方式,懒汉式和饿汉式。(1)懒汉式,就是只有当调用getInstance的时候,才会初始化这个单例。(2)饿汉式,就是一旦... -
【Java】单例模式——懒汉式和饿汉式
2020-07-22 09:41:36public class DanLi { private DanLi() { System.out.println("单例"); } //饿汉式 一开始就开辟一块内存地址,比较浪费内存 // private static DanLi dl=new DanLi... //懒汉式 需要调用时再开辟内存地址,. -
Java中单例模式(懒汉式和饿汉式)
2021-04-01 11:27:45* 饿汉式创建单例 */ public class Singleton { public static Singleton INSTANCE = new Singleton(); private Singleton(){} } 上面该方法是饿汉式创建单例,public访问修饰符可以在其他包下访问,static... -
java单例设计模式之懒汉式和饿汉式
2020-04-05 20:23:40} } 饿汉式和懒汉式的区别: 饿汉式: 优点:线程是安全的。 缺点:对象加载时间过长。 懒汉式: 优点:延迟对象的创建 缺点:存在线程安全问题,可以使用多线程锁来解决。 单例模式的优点: 由于单例模式只生成一... -
Java单例模式--懒汉式和饿汉式(Demo)
2020-06-02 10:23:47你好我是辰兮,很高兴你能来阅读,本篇文章为大家讲解Java多线程之synchronized关键词,下面有案例的截图和相关...文章目录一、序言二、饿汉式三、懒汉式四、好奇的小结 一、序言 单件模式属于工厂模式的特例,只是. -
Java单例模式的懒汉式和饿汉式的实现
2020-09-12 10:30:07懒汉模式: /** * @author baikunlong * @date 2020/9/12 9:20 * 单例模式1 懒汉模式 */ public class Single1 { //加上volatile关键字,解决双重检测的超小几率翻车,达到百分百单例 private static ...