-
2017-06-08 12:16:34
单例模式使用于:只能打开一个对象实例时。
/**
*
* @author dhf
*单例模式
*/
public class Singleton {
//定义一个静态变量对象 缓存存储生成的对象
public static Singleton sgl;
//构造器进行隐藏,用private修饰
private Singleton(){
}
public static Singleton getSingleton(){
if (sgl== null ){
sgl = new Singleton();
// return sgl;
}
return sgl;
}
public static void main(String args[]){
//创建对象不能通过构造器,只能通过get方法。
Singleton sgl = Singleton.getSingleton();
if(sgl != null){
System.out.println("非空打印");
}
Singleton sgl2 = Singleton.getSingleton();
if (sgl ==sgl2){
System.out.println("打印相等");
}
}}
更多相关内容 -
java单例模式实例
2018-07-17 18:51:20一个简单的java工程,包含注释,一目了然,其中包含了单例模式的所有实现方式,懒汉式,饿汉式,双重校验,枚举,静态内部类等方式实现单例。 -
Java单例模式实例简述
2020-09-04 04:01:23主要介绍了Java单例模式,在Java应用程序设计中有着非常重要的作用,本文以实例形式对此加以简单分析,需要的朋友可以参考下 -
Java单例模式和多例模式实例分析
2020-08-25 19:25:22主要介绍了Java单例模式和多例模式,结合实例形式分析了java单例模式与多例模式的定义及使用技巧,需要的朋友可以参考下 -
Java单例模式简单示例
2020-08-30 04:12:59主要介绍了Java单例模式,结合实例形式简单分析了java单例模式的定义与使用技巧,需要的朋友可以参考下 -
java 单例模式的实例详解
2021-03-10 07:42:25java 单例模式的实例详解概念:java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。单例模式有一下特点:1、单例类只能有一个实例。2、单例类必须自己自己创建自己的...java 单例模式的实例详解
概念:
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
首先看一个经典的单例实现。
public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Other methods...
}
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)
但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。
public class TestStream {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//该类只能有一个实例
private TestStream(){} //私有无参构造方法
//该类必须自行创建
//有2种方式
/*private static final TestStream ts=new TestStream();*/
private static TestStream ts1=null;
//这个类必须自动向整个系统提供这个实例对象
public static TestStream getTest(){
if(ts1==null){
ts1=new TestStream();
}
return ts1;
}
public void getInfo(){
System.out.println("output message "+name);
}
}
/**
*
*/
public class TestMain {
public static void main(String [] args){
TestStream s=TestStream.getTest();
s.setName("张孝祥");
System.out.println(s.getName());
TestStream s1=TestStream.getTest();
s1.setName("张孝祥");
System.out.println(s1.getName());
s.getInfo();
s1.getInfo();
if(s==s1){
System.out.println("创建的是同一个实例");
}else if(s!=s1){
System.out.println("创建的不是同一个实例");
}else{
System.out.println("application error");
}
}
}
运行结果:
张孝祥
张孝祥
output message 张孝祥
output message 张孝祥
创建的是同一个实例
结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。
1.饿汉式单例类
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
//私有的默认构造子
private Singleton1() {}
//已经自行实例化
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
2.懒汉式单例类
//懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
//私有的默认构造子
private Singleton2() {}
//注意,这里没有final
private static Singleton2 single=null;
//静态工厂方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
3.登记式单例类
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 {
private static Map map = new HashMap();
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 单例模式的实例详解全部内容,希望文章能够帮你解决java 单例模式的实例详解所遇到的程序开发问题。
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250
-
java 单例模式和工厂模式实例详解
2020-08-30 19:52:45主要介绍了Java设计模式编程中的单例模式和简单工厂模式以及实例,使用设计模式编写代码有利于团队协作时程序的维护,需要的朋友可以参考下 -
JAVA 枚举单例模式及源码分析的实例详解
2020-08-29 18:49:27主要介绍了 JAVA 枚举单例模式及源码分析的实例详解的相关资料,需要的朋友可以参考下 -
Java设计模式之单例模式实例详解【懒汉式与饿汉式】
2020-08-29 08:14:27主要介绍了Java设计模式之单例模式,简单说明了单例模式的原理并结合具体实例形式分析了单例模式中懒汉式与饿汉式的具体实现与使用技巧,需要的朋友可以参考下 -
java单例模式——详解JAVA单例模式及8种实现方式
2022-03-21 16:28:53单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能...## 单例模式是最简单也是最基础的设计模式之一,下边一起学习一下单例模式!
一.单例模式的定义:
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。二.单例模式的特点
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性。三.线程安全问题:
一方面在获取单例的时候,要保证不能产生多个实例对象,后面会详细讲到五种实现方式;
另一方面,在使用单例对象的时候,要注意单例对象内的实例变量是会被多线程共享的,推荐使用无状态的对象,不会因为多个线程的交替调度而破坏自身状态导致线程安全问题,比如我们常用的VO,DTO等(局部变量是在用户栈中的,而且用户栈本身就是线程私有的内存区域,所以不存在线程安全问题)。四.实现单例模式的八种方式:
1.饿汉式(静态常量)【可用】
优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
2.饿汉式(静态代码块)【可用】
这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的。
3.懒汉式(线程不安全)【不可用】
这种写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。
4.懒汉式(线程安全,同步方法)【不推荐用】
解决上面第三种实现方式的线程不安全问题,做个线程同步就可以了,于是就对getInstance()方法进行了线程同步。
缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。
5.懒汉式(线程安全,同步代码块)【不可用】
由于第四种实现方式同步效率太低,所以摒弃同步方法,改为同步产生实例化的的代码块。但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。
6.双重检查【推荐使用】
Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。
优点:线程安全;延迟加载;效率较高。
7.静态内部类【推荐使用】
这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。
类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
优点:避免了线程不安全,延迟加载,效率高。
8.枚举【推荐使用】
借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。
五.单例模式的优点
系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
六.单例模式的缺点
当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其他开发人员造成困扰,特别是看不到源码的时候。
七.单例模式的使用场景
需要频繁的进行创建和销毁的对象;
创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
工具类对象;
频繁访问数据库或文件的对象。 -
java 单例模式(懒汉式与饿汉式)
2020-08-29 22:17:24主要介绍了java 单例模式的相关资料,这里对懒汉式与饿汉式都做了实例介绍,需要的朋友可以参考下 -
java 单例模式(饿汉模式与懒汉模式)
2021-01-03 04:24:11java 单例模式 饿汉式单例 对于饿汉模式,我们可这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象。 懒汉式单例类 对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身... -
java单例模式看这一篇就够了
2020-12-21 05:06:15深入分析java单例模式什么是单例模式单例模式的常见写法一、饿汉式单例优点缺点示例二、懒汉式单例示例1(普通写法)示例2(synchronized写法)示例3(DCL写法)示例4(内部类写法)三、注册式单例示例1(容器式)示例2(枚举式... -
Java设计模式之单例模式实例分析
2020-09-03 05:04:44主要介绍了Java设计模式之单例模式,以实例形式较为详细的分析了单例模式的概念、定义及简单实现技巧,需要的朋友可以参考下 -
Java单例模式个人总结(实例变量和类变量)
2020-12-09 16:25:36Java单例模式 背景知识:Static关键字。 在对于定义类的变量,分为两种,是否具有static修饰的变量; 没有static修饰的变量,通过类的实例化(对象)引用,改变量称为实例变量; 使用static修饰的变量称之为类...Java单例模式
-
背景知识:Static关键字。
-
在对于定义类的变量,分为两种,是否具有static修饰的变量;
- 没有static修饰的变量,通过类的实例化(对象)引用,改变量称为实例变量;
- 使用static修饰的变量称之为类变量(也称之静态变量),类变量不通过类的实例化来引用,可类名直接引用;
-
二者区别:
- 实例变量: JVM为每个新创建的对象分配独立的内存空间;
- 类变量: 是所有对象共有的;
-
引用方式:
- 实例变量: 对象名.变量名
- 类变量: 类名.变量名
-
使用类变量的优点:减少开辟新的内存空间,直接引用固有变量。
-
本概念也可以引入至实例方法和类方法;
-
定义:该类只有一个实例,并且自行实例化向整个系统提供该实例;(由如一个国家只有一个皇帝,并只能指定某个人为皇帝);
-
单例模式是应用最广泛的模式之一:
-
作用:单例模式可以避免系统创建过多对象,从而减少过多资源消耗;
-
适用场景:
- 该系统资源只具有该类一个实例化对象:例如改家公司只具有一个打印机;
- 创建一个对象,需消耗的资源过多的情况下,可以使用单例模式。(例:访问IO和数据库连接池建立);
-
注意点:
- 构造方法不对外开放,一般为Private;
- 单例模式的构造函数私有化,使得客户端代码无法以New 的方式实例化该类对象,只会暴露一个公有化静态方法;
例: Person person = new Person(); Connection connection = DruidUtils.getConnection();
懒汉模式
- 特点:当使用时才进行实例化,采用以时间换空间的方式;
- 优点:一定程度上节约资源;
- 缺点:第一次加载时才进行实例化,反应慢;
饿汉模式
- 特点:调用时,即进行类的实例化,采用以空间换时间的方式;
代码参考:将单例模式与计算正方形面积结合在一起;
- AreaHunger:
package singleinstance; public class AreaHunger { // Create an instance directly. private static AreaHunger instance = new AreaHunger(); // Private constructor. Can't visit it from outside's class. private AreaHunger() { } // Return an instance directly. public static AreaHunger getInstance() { return instance; } // Caculate the square area. public static UserTest getHunger(int x) { System.out.println("The square area are " + (x*x)); return null; } }
- AreaLazy:
package singleinstance; public class AreaLazy { // In inner to create an instance. private static AreaLazy instance = null; // Private constructor. Can't visit it from outside's class. private AreaLazy() { } // Provide a public static method to visit from outside. public static AreaLazy getInstance() { if(instance == null) { return new AreaLazy(); } return new AreaLazy(); } // Caculate the square's area. public static UserTest getSquareArea(int x) { System.out.println("The square are are " + (x*x)); return null; } }
- UserTest(用于测试):
public class UserTest { public static void main(String[] args) { // TODO Auto-generated method stub UserTest manOne = AreaLazy.getSquareArea(4); UserTest manTwo = AreaHunger.getHunger(8); } }
- Console:(控制台运行结果)
The square are are 16 The square area are 64
-
-
Java单例模式、饥饿模式代码实例
2020-09-03 17:19:35主要介绍了Java单例模式、饥饿模式代码实例,本文直接给出代码实例,需要的朋友可以参考下 -
Java单例模式下的MongoDB数据库操作工具类
2020-08-28 08:14:38主要介绍了Java单例模式下的MongoDB数据库操作工具类,结合实例形式分析了java基于单例模式下操作MongoDB数据库相关连接、查询、插入、删除等操作封装技巧,需要的朋友可以参考下 -
Java 单例模式
2021-05-28 16:11:05单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个... -
实例解析Java单例模式编程中对抽象工厂模式的运用
2020-09-02 20:08:12主要介绍了实例解析Java单例模式编程中对抽象工厂模式的运用,抽象工厂模式可以看作是工厂方法模式的升级版,本需要的朋友可以参考下 -
使用java时间连接池连接redis,单例模式和集群模式.docx
2019-07-09 21:19:18使用java客户端连接Redis 集群,并使用java进行简单的操作 -
图解Java单例模式内存分配
2021-01-21 17:14:381:虚拟机加载StaticDemo类,保存类型信息到方法区。... (1)装载,通过类的全名产生对应类的二进制数据流,分析二进制数据流并转换为方法区特定的数据结构,创建对应类的java.lang.Class实例。 (2)链 -
java单例模式
2021-03-06 06:25:11单例模式就是始终是一个对象实例.它对外不提供构造函数,因此我们不能够同时产生多个对象.(常用语工具类,数据库连接类等等)单例模式的调用:因为单例模式的构造方法是私有的,所以在其他类中我们是没有办法直接实例化它... -
JAVA单例模式
2021-02-12 18:32:20定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。类型:创建类模式类图:类图知识点:1....单例模式应该是23种设计模式中最简单的一种模式了。它有以下几个要素:• 私有的... -
java 单例模式 ---饿汉式懒汉式
2022-01-28 13:37:37目录 单例设计模式 饿汉式 懒汉式 饿汉式vs懒汉式 ...饿汉式:在程序启动或单例模式类被加载的时候,单例模式实例就已经被创建。 上例子! package com.happy.demo; public class Singleton...