当前位置:首页 » 编程语言 » 懒汉单例模式java

懒汉单例模式java

发布时间: 2023-04-13 15:02:09

java的单例模式到底有几种变现形式请列举

JAVA单例模式的几种实现方法
1.饿汉式单例类
package pattern.singleton;
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
//私有的默认构造子
private Singleton1() {}
//已经自行实例化
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}

2.懒汉式单例类
package pattern.singleton;
//懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
//私有的默认构造子
private Singleton2() {}

//注意,这里没有final
private static Singleton2 single;

//只实例化一次
static{
single = new Singleton2();
}

//静态工厂方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化,以处理多线程环境。有些设计师在这里建议使用所谓的"双重检查成例".必须指出的是,"双重检查成例"不可以在Java 语言中使用。不十分熟悉的读者,可以看看后面腔或给出的小节。 同样液者,由于构造子是私有的,因此,此类不能被继承。饿汉式单例类在自己被加载时就将自己实例化。即便加载器是静态的,在饿汉式单例类被加载时仍会将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,必须处
理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费时间。这意味着出现多线程同时首次引用此类的机率变得较大。
饿汉式单例类可以在Java 语言内实现, 但不易在C++ 内实现,因为静态初始化在C++ 里没有固定的顺序,因而静态的m_instance 变量的初始化与类的加载顺序没有保证,可能会出问题。这就是为什么GoF 在提出单例类的概念时,举的例子是懒汉式的。他们的书影响之大,以致Java 语言中单例类的例子也大多是懒汉式的。实际上,本书认为饿汉式单例类更符合Java 语言本身的特点。

3.登记式单例类.
package pattern.singleton;

import java.util.HashMap;
import java.util.Map;

//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。

public class Singleton3 {
private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}

//保护的默认构伍埋伍造子
protected Singleton3(){}

//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"--->name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}

//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}

㈡ 请教 Java设计模式中的单例模式的懒汉式和饿汉式名字的由来,为什么叫懒汉式 饿汉式

所谓“举袜懒汉式正滑激”与“饿汉式”的区别,是在与建立单例对象的时间不同。
“懒汉式”是在你真正用到的时候才去建这个单例对象:
比如:有个单例对象
private static Student student = null; //不建立对象
Student getInstance(){
if(student == null) { //先判断是否为空
student = new Student(); //懒汉式做法
}
return student;
}

“饿汉式”是在不管你用的用不上,一开始就建立这个单例对象:
比如:有个单例对象
private static Student student = new Student(); //建立对象
Student getInstance(){
return student; //直接返回单例对让镇象
}

㈢ JAVA单例模式有哪些

一、懒汉式单例x0dx0a在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。x0dx0a x0dx0apublic class LazySingleton {x0dx0a /**x0dx0a * 私有静态对象,加载时候不做初始化x0dx0a */x0dx0a private static LazySingleton m_intance=null;x0dx0a /**x0dx0a * 私有构造方法,避免外部创建实例x0dx0a */x0dx0a private LazySingleton(){x0dx0a }x0dx0a /**x0dx0a * 静态工厂方法,返回此类的唯一实例. x0dx0a * 当发现实例没有初始化的时候,才初始化.x0dx0a */x0dx0a synchronized public static LazySingleton getInstance(){x0dx0a if(m_intance==null){x0dx0a m_intance=new LazySingleton();x0dx0a }x0dx0a return m_intance;x0dx0a }x0dx0a}x0dx0ax0dx0a二、饿汉式单例x0dx0a在类被加载的时候,唯一实例已经被创建。x0dx0a x0dx0apublic class EagerSingleton {x0dx0a /**x0dx0a * 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象x0dx0a */x0dx0a private static final EagerSingleton m_instance = new EagerSingleton();x0dx0a /**x0dx0a * 私有构造方法,避免外部创建实例x0dx0a */x0dx0a private EagerSingleton() {x0dx0a }x0dx0a /**x0dx0a * 静态工厂方法,返回此类的唯一实例.x0dx0a * @return EagerSingletonx0dx0a */x0dx0a public static EagerSingleton getInstance() {x0dx0a return m_instance;x0dx0a }x0dx0a}x0dx0a x0dx0a************************************************************************************** 懒汉方式,指全局的单例实例在第一次被使用时构建; x0dx0a饿汉方式,指全局的单例实例在类装载时构建 x0dx0a**************************************************************************************x0dx0ax0dx0a三、登记式单例x0dx0a这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。x0dx0apublic class RegSingleton {x0dx0a /**x0dx0a * 登记薄,用来存放所有登记的实例x0dx0a */x0dx0a private static Map m_registry = new HashMap();x0dx0a //在类加载的时候添加一个实例到登记薄x0dx0a static {x0dx0a RegSingleton x = new RegSingleton();x0dx0a m_registry.put(x.getClass().getName(), x);x0dx0a }x0dx0a /**x0dx0a * 受保护的默认构造方法x0dx0a */x0dx0a protected RegSingleton() {x0dx0a }x0dx0a /**x0dx0a * 静态工厂方法,返回指定登记对象的唯一实例;x0dx0a * 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回x0dx0a * @param namex0dx0a * @return RegSingletonx0dx0a */x0dx0a public static RegSingleton getInstance(String name) {x0dx0a if (name == null) {x0dx0a name = "RegSingleton";x0dx0a }x0dx0a if (m_registry.get(name) == null) {x0dx0a try {x0dx0a m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());x0dx0a } catch (InstantiationException e) {x0dx0a e.printStackTrace();x0dx0a } catch (IllegalAccessException e) {x0dx0a e.printStackTrace();x0dx0a } catch (ClassNotFoundException e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a }x0dx0a return m_registry.get(name);x0dx0a }x0dx0a /**x0dx0a * 一个示意性的商业方法x0dx0a * @return Stringx0dx0a */x0dx0a public String about() {x0dx0a return "Hello,I am RegSingleton!";x0dx0a }x0dx0a}

㈣ Java单例模式是什么意思

  1. Java单例模式是确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例的模式;

  2. Java单例模式分三种:懒汉式单例、饿汉式单例、登记式单例。

㈤ java里的单例模式是不是就是相当于c中的全局

个人理解,是的,java的单例模式代表只有一个对象的建立,和C里面的全局变量是一个意思

㈥ java 中 单实例和多实例是指的什么

简单的说单例就是
只能有一个实例,所以地方用到的实例都是同一个。
就好像家人吃饭,桌子是单例的,大家用的是同一个。而碗是多例的,每人都有自几的。
下面是具体的例子:
Java模式之单例模式:

单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。

特点:

1,一个类只能有一个实例

2,自己创建这个实例

3,整个系统都要使用这个实例

例:
在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙"
和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录
数据库连接都需要这样的单线程操作。一些资源治理器经常设计成单例模式。

外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer
Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中治理这些通信端口,以避免一个通信端口被两个请求同时调用。内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来治理这些属性文件。一个例子:Windows
回收站。
在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。
两种形式:
1,饿汉式单例类
public
class
Singleton
{
private
Singleton(){}
//在自己内部定义自己一个实例,是不是很希奇?

//注重这是private
只供内部调用
private
static
Singleton
instance
=
new
Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问

public
static
Singleton
getInstance()
{

return
instance;

}
}
2,懒汉式单例类
public
class
Singleton
{
private
static
Singleton
instance
=
null;
public
static
synchronized
Singleton
getInstance()
{
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次

//使用时生成实例,提高了效率!

if
(instance==null)

instance=new
Singleton();

return
instance;
}
}
第二中形式是lazy
initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。
注重到lazy
initialization形式中的synchronized,这个synchronized很重要,假如没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。
一般来说第一种比较安全。进入讨论组讨论。

㈦ JAVA单例模式有哪些

一、懒汉式单例
在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实缓拍李例。

public class LazySingleton {
/**
* 私有静态对象,加载时候不做初始化
*/
private static LazySingleton m_intance=null;
/**
* 私有构造方法,避免外部创建实例
*/
private LazySingleton(){
}
/**
* 静态工厂方法,返回此类的唯一实例.
* 当发现实例没有初始化的时候,才初始化.
*/
synchronized public static LazySingleton getInstance(){
if(m_intance==null){
m_intance=new LazySingleton();
}
return m_intance;
}
}

二、饿汉式单例
在类被加载的时候,唯一实例已经被创建。

public class EagerSingleton {
/**
* 私有的(private)唯一(static final)实例成员,在类加载的时候就扰迟创建好了单例对象
*/
private static final EagerSingleton m_instance = new EagerSingleton();
/**
* 私有构造方法,避免外部创建实例
*/
private EagerSingleton() {
}
/**
* 静态工厂方法,返回此类的唯一实例.
* @return EagerSingleton
*/
public static EagerSingleton getInstance() {
return m_instance;
}
}

************************************************************************************** 懒汉方式,指全局的单例实例在第一次被使用时构建;
饿汉方式,指全局的单例实例在类装载时构建
**************************************************************************************

三、登记式单例
这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。贺并
public class RegSingleton {
/**
* 登记薄,用来存放所有登记的实例
*/
private static Map<String, RegSingleton> m_registry = new HashMap();
//在类加载的时候添加一个实例到登记薄
static {
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
}
/**
* 受保护的默认构造方法
*/
protected RegSingleton() {
}
/**
* 静态工厂方法,返回指定登记对象的唯一实例;
* 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回
* @param name
* @return RegSingleton
*/
public static RegSingleton getInstance(String name) {
if (name == null) {
name = "RegSingleton";
}
if (m_registry.get(name) == null) {
try {
m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return m_registry.get(name);
}
/**
* 一个示意性的商业方法
* @return String
*/
public String about() {
return "Hello,I am RegSingleton!";
}
}

㈧ JAVA中单例模式懒汉式 成员变量为什么要赋值为空成员变量虚拟机不是会给它自动赋值么

应该是一种习惯,其次可能是因为他是静态的,静态的变量,无论类被实例化几次,他的值都是不会改变的,照你这么说,成员变量余缓会自动粗慎赋值,但是他的值在实例化N次之后并没有变化,总的来说,这是这个种好习惯,就怕不同平台赋予的初始值竖凳模不相同。

㈨ java如何只存一次数据

在Java中只存储一次数据可以使用单例模式来弊升实现。单例模式是一种常用的设计模式,它可以保证一个类只租氏老核明有一个实例,并提供一个全局访问点。在实现单例模式时,一般采用懒汉式或饿汉式两种方式。
1、饿汉式单例模式:在类加载时就创建实例。
2、懒汉式单例模式:在第一次使用时才创建实例。

㈩ Java模式设计之单例模式(一)

作为对象的创建模式[GOF ] 单例模式确保某一个类只有一个实例 而且自行实例化并向整个系统提供这个实例 这个类称为单例类

单例模式的要点

单例单例

显然单例模式的要点有三个 一是某各类只能有一个实例 二是它必须自行创建这个事例 三是它必须自行向整个系统提供这个实例 在下面的对象图中 有一个 单例对象 而 客户甲 客户乙 和 客户丙 是单例对象的三个客户对象 可以看到 所有的客户对象共享一个单例对象 而且从单例对象到自身的连接线可以看出 单例对象持有对自己的引用

资源管理

一些资源管理器常常设计成单例模式

在计算机系统中 需要管理的资源包括软件外部资源 譬如每台计算机可以有若干个打印机 但只能有一个Printer Spooler 以避免两个打印作业同时输出到打印机中 每台计算机可以有若干传真卡 但是只应该有一个软件负责管理传真卡 以避免出现两份传真作业同时传到传真卡中的情况 每台计算机可以有若干通信端口 系统应当集中管理这些通信端口 以避免一个通信端口同时被两个请求同时调用

需要管理的资源包括软件内部资源 譬如 大多数的软件都有一个(甚至多个)属性(properties)文件存放系统配置 这样的系统应当由一个对象来管理一个属性文件

需要管理的软件内部资源也包括譬如负责记录网站来访人数的部件 记录软件系统内部事件 出错信息的部件 或是对系统的表念蚂现进行检查的部件等 这些部件都必须集中管理 不可政出多头

这些资源管理器构件必须只有一个实例 这是其一 它们必须自行初始化 这是其二 允许整个系统访问自己这是其三 因此 它们都满足单例模式的条件 是单例模式的应用

一个例子 Windows 回收站

Windows x 以后的视窗系统中都有一个回收站 下图就显示了Windows 的回收站

在整个视窗系尘高核统中 回收站只能有一个实例 整个系统都使用这个惟一的实例 而且回收站自行提供自己的实例 因此 回收站是单例模式的应用

双重检查成例

在本章最后的附录里研究了双重检查成例 双重检查成例与单例模式并无直接的关系 但是由于很多C 语言设计师在单例模式里面使用双重检查成例 所以这一做法也被很多Java 设计师所模仿 因此 本书在附录里提醒读者 双重检查成例在Java 语言里并不能成立 详情请见本章的附录

单例模式的结构

单例模式有以下的特点

…… 单例类只可有一个实例

…… 单例类必须自己创建自己这惟一的实例

…… 单例类必须给所有其他对象提供这一实例

虽然单例模式中的单例类被限定只能有一个实例 但是单例模式和单例类可以很容易被推广到任意且有限多个实例的情况 这时候称它为多例模式(Multiton Pattern) 和多例类(Multiton Class) 请见 专题 多例(Multiton )模式与多语言支持 一章 单例类的简略类图如下所示

由于Java 语言的特点 使得单例模式在Java 语言的实现上有自己的特点 这些特点主要表现在单例类如何将自己实例化上

饿汉式单例类饿汉式单例类是在Java 语言里实现得最为简便的单例类 下面所示的类图描述了一个饿汉式单例类的典型实现

从图中可以看出 此类已经自已将自己实例化

代码清单 饿汉式单例类

public class EagerSingleton { private static final EagerSingleton m_instance = new EagerSingleton() /** * 私有的默认构造子*/ private EagerSingleton() { } /** * 静态工厂方法*/ public static EagerSingleton getInstance()

{

Java 与模式return m_instance }

读者可以看出 在这个类被加载时 静态变量m_instance 会被初始化 此时类的私有构造子会被调用 这时候 单例类的惟一实例就被创建出来了

Java 语言中单例类的一个最重要的特点是类派掘的构造子是私有的 从而避免外界利用构造子直接创建出任意多的实例 值得指出的是 由于构造子是私有的 因此 此类不能被继承

懒汉式单例类

与饿汉式单例类相同之处是 类的构造子是私有的 与饿汉式单例类不同的是 懒汉式单例类在第一次被引用时将自己实例化 如果加载器是静态的 那么在懒汉式单例类被加载时不会将自己实例化 如下图所示 类图中给出了一个典型的饿汉式单例类实现

代码清单 懒汉式单例类

package javapatterns singleton demos public class LazySingleton { private static LazySingleton m_instance = null /** * 私有的默认构造子 保证外界无法直接实例化*/ private LazySingleton() { } /** * 静态工厂方法 返还此类的惟一实例*/ synchronized public static LazySingleton getInstance()

{ if (m_instance == null)

{ m_instance = new LazySingleton() } return m_instance }

读者可能会注意到 在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化 以处理多线程环境 有些设计师在这里建议使用所谓的 双重检查成例 必须指出的是 双重检查成例 不可以在Java 语言中使用 不十分熟悉的读者 可以看看后面给出的小节

同样 由于构造子是私有的 因此 此类不能被继承 饿汉式单例类在自己被加载时就将自己实例化 即便加载器是静态的 在饿汉式单例类被加载时仍会将自己实例化 单从资源利用效率角度来讲 这个比懒汉式单例类稍差些

从速度和反应时间角度来讲 则比懒汉式单例类稍好些 然而 懒汉式单例类在实例化时 必须处理好在多个线程同时首次引用此类时的访问限制问题 特别是当单例类作为资源控制器 在实例化时必然涉及资源初始化 而资源初始化很有可能耗费时间 这意味着出现多线程同时首次引用此类的机率变得较大

饿汉式单例类可以在Java 语言内实现 但不易在C++ 内实现 因为静态初始化在C++ 里没有固定的顺序 因而静态的m_instance 变量的初始化与类的加载顺序没有保证 可能会出问题 这就是为什么GoF 在提出单例类的概念时 举的例子是懒汉式的 他们的书影响之大 以致Java 语言中单例类的例子也大多是懒汉式的 实际上 本书认为饿汉式单例类更符合Java 语言本身的特点

登记式单例类

登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的 本书把他们的例子翻译为Java 语言 并将它自己实例化的方式从懒汉式改为饿汉式 只是它的子类实例化的方式只能是懒汉式的 这是无法改变的 如下图所示是登记式单例类的一个例子 图中的关系线表明 此类已将自己实例化

代码清单 登记式单例类

import java util HashMap public class RegSingleton { static private HashMap m_registry = new HashMap() static { RegSingleton x = new RegSingleton() m_registry put( x getClass() getName() x) } /** * 保护的默认构造子*/ protected RegSingleton() {} /** * 静态工厂方法 返还此类惟一的实例*/ static public RegSingleton getInstance(String name)

{ if (name == null)

{ name = javapatterns singleton demos RegSingleton } if (m_registry get(name) == null)

{ try { m_registry put( name Class forName(name) newInstance() ) } catch(Exception e)

{ System out println( Error happened ) } return (RegSingleton) (m_registry get(name) ) } /** * 一个示意性的商业方法*/ public String about()

{ return Hello I am RegSingleton }它的子类RegSingletonChild 需要父类的帮助才能实例化 下图所示是登记式单例类子类的一个例子 图中的关系表明 此类是由父类将子类实例化的

下面是子类的源代码

代码清单 登记式单例类的子类

import java util HashMap public class RegSingletonChild extends RegSingleton { public RegSingletonChild() {} /** * 静态工厂方法*/ static public RegSingletonChild getInstance()

{ return (RegSingletonChild)

RegSingleton getInstance( javapatterns singleton demos RegSingletonChild ) } /** * 一个示意性的商业方法*/ public String about()

{ return Hello I am RegSingletonChild }

在GoF 原始的例子中 并没有getInstance() 方法 这样得到子类必须调用的getInstance(String name)方法并传入子类的名字 因此很不方便 本章在登记式单例类子类的例子里 加入了getInstance() 方法 这样做的好处是RegSingletonChild 可以通过这个方法 返还自已的实例 而这样做的缺点是 由于数据类型不同 无法在RegSingleton 提供这样一个方法 由于子类必须允许父类以构造子调用产生实例 因此 它的构造子必须是公开的 这样一来 就等于允许了以这样方式产生实例而不在父类的登记中 这是登记式单例类的一个缺点

lishixin/Article/program/Java/gj/201311/27416

热点内容
centos升级python27 发布:2024-11-02 02:00:57 浏览:673
ue4未找到编译器 发布:2024-11-02 01:46:08 浏览:155
python中的withopen 发布:2024-11-02 01:46:07 浏览:976
编程名人 发布:2024-11-02 01:42:18 浏览:867
服务器电脑配置表 发布:2024-11-02 01:41:29 浏览:370
linux使用串口 发布:2024-11-02 01:37:11 浏览:702
二维码扫的密码从哪里开始 发布:2024-11-02 01:24:57 浏览:473
如何将手表改成开放式安卓系统 发布:2024-11-02 01:09:00 浏览:739
6s还能用吗能和什么安卓机比 发布:2024-11-02 01:08:09 浏览:765
SQL扩位 发布:2024-11-02 00:55:35 浏览:447