java写一个单例模式(如何写一个标准的Java单例模式)

2025-03-30 09:00:02 0

java写一个单例模式(如何写一个标准的Java单例模式)

本文目录

如何写一个标准的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 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 static void main(String args) {TestStream s = TestStream.getTest();s.setName(“张孝祥 1“);System.out.println(s.getName());TestStream s1 = TestStream.getTest();s1.setName(“张孝祥 2“);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“);}}}////////////////////////////////////////////

如何用Java实现单例模式

单例模式:就是一个类仅创建一个对象;

public class Singleton {    private static volatile Singleton singleton = null;     private Singleton(){}// 构造方法     public static Singleton getSingleton(){// 单例模式        if(singleton == null){            synchronized (Singleton.class){                if(singleton == null){                    singleton = new Singleton();                }            }        }        return singleton;    }    }

java中的单例模式的代码怎么写

我从我的博客里把我的文章粘贴过来吧,对于单例模式模式应该有比较清楚的解释:单例模式在我们日常的项目中十分常见,当我们在项目中需要一个这样的一个对象,这个对象在内存中只能有一个实例,这时我们就需要用到单例。一般说来,单例模式通常有以下几种:1.饥汉式单例public class Singleton { private Singleton(){}; private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; }}这是最简单的单例,这种单例最常见,也很可靠!它有个唯一的缺点就是无法完成延迟加载——即当系统还没有用到此单例时,单例就会被加载到内存中。在这里我们可以做个这样的测试:将上述代码修改为:public class Singleton { private Singleton(){ System.out.println(“createSingleton“); }; private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } public static void testSingleton(){ System.out.println(“CreateString“); }}而我们在另外一个测试类中对它进行测试(本例所有测试都通过Junit进行测试)public class TestSingleton { @Test public void test(){ Singleton.testSingleton(); }}输出结果:createSingletonCreateString 我们可以注意到,在这个单例中,即使我们没有使用单例类,它还是被创建出来了,这当然是我们所不愿意看到的,所以也就有了以下一种单例。2.懒汉式单例public class Singleton1 { private Singleton1(){ System.out.println(“createSingleton“); } private static Singleton1 instance = null; public static synchronized Singleton1 getInstance(){ return instance==null?new Singleton1():instance; } public static void testSingleton(){ System.out.println(“CreateString“); }}上面的单例获取实例时,是需要加上同步的,如果不加上同步,在多线程的环境中,当线程1完成新建单例操作,而在完成赋值操作之前,线程2就可能判断instance为空,此时,线程2也将启动新建单例的操作,那么多个就出现了多个实例被新建,也就违反了我们使用单例模式的初衷了。我们在这里也通过一个测试类,对它进行测试,最后面输出是CreateString可以看出,在未使用到单例类时,单例类并不会加载到内存中,只有我们需要使用到他的时候,才会进行实例化。这种单例解决了单例的延迟加载,但是由于引入了同步的关键字,因此在多线程的环境下,所需的消耗的时间要远远大于第一种单例。我们可以通过一段测试代码来说明这个问题。public class TestSingleton { @Test public void test(){ long beginTime1 = System.currentTimeMillis(); for(int i=0;i《100000;i++){ Singleton.getInstance(); } System.out.println(“单例1花费时间:“+(System.currentTimeMillis()-beginTime1)); long beginTime2 = System.currentTimeMillis(); for(int i=0;i《100000;i++){ Singleton1.getInstance(); } System.out.println(“单例2花费时间:“+(System.currentTimeMillis()-beginTime2)); }}最后输出的是:单例1花费时间:0单例2花费时间:10 可以看到,使用第一种单例耗时0ms,第二种单例耗时10ms,性能上存在明显的差异。为了使用延迟加载的功能,而导致单例的性能上存在明显差异,是不是会得不偿失呢?是否可以找到一种更好的解决的办法呢?既可以解决延迟加载,又不至于性能损耗过多,所以,也就有了第三种单例:3.内部类托管单例public class Singleton2 { private Singleton2(){} private static class SingletonHolder{ private static Singleton2 instance=new Singleton2(); } private static Singleton2 getInstance(){ return SingletonHolder.instance; }}在这个单例中,我们通过静态内部类来托管单例,当这个单例被加载时,不会初始化单例类,只有当getInstance方法被调用的时候,才会去加载SingletonHolder,从而才会去初始化instance。并且,单例的加载是在内部类的加载的时候完成的,所以天生对线程友好,而且也不需要synchnoized关键字,可以说是兼具了以上的两个优点。4.总结一般来说,上述的单例已经基本可以保证在一个系统中只会存在一个实例了,但是,仍然可能会有其他的情况,导致系统生成多个单例,请看以下情况:public class Singleton3 implements Serializable{ private Singleton3(){} private static class SingletonHolder{ private static Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance(){ return SingletonHolder.instance; }}通过一段代码来测试:@Test public void test() throws Exception{ Singleton3 s1 = null; Singleton3 s2 = Singleton3.getInstance(); //1.将实例串行话到文件 FileOutputStream fos = new FileOutputStream(“singleton.txt“); ObjectOutputStream oos =new ObjectOutputStream(fos); oos.writeObject(s2); oos.flush(); oos.close(); //2.从文件中读取出单例 FileInputStream fis = new FileInputStream(“singleton.txt“); ObjectInputStream ois = new ObjectInputStream(fis); s1 = (Singleton3) ois.readObject(); if(s1==s2){ System.out.println(“同一个实例“); }else{ System.out.println(“不是同一个实例“); } }输出:不是同一个实例 可以看到当我们把单例反序列化后,生成了多个不同的单例类,此时,我们必须在原来的代码中加入readResolve()函数,来阻止它生成新的单例public class Singleton3 implements Serializable{ private Singleton3(){} private static class SingletonHolder{ private static Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance(){ return SingletonHolder.instance; } //阻止生成新的实例 public Object readResolve(){ return SingletonHolder.instance; }}再次测试时,就可以发现他们生成的是同一个实例了。

java写一个单例模式(如何写一个标准的Java单例模式)

本文编辑:admin

更多文章:


暴力破解软件(我的EXCEL忘记了密码,谁有暴力破解的软件,)

暴力破解软件(我的EXCEL忘记了密码,谁有暴力破解的软件,)

本文目录我的EXCEL忘记了密码,谁有暴力破解的软件,有没有破解压缩文件密码的软件哪种wifi万能钥匙最好,解码最厉害谁给我个暴力破解软件暴力破解软件什么软件可以暴力破解WiFi暴力破解应用程序是什么意思我的EXCEL忘记了密码,谁有暴力破

2025年3月13日 12:50

breakdown是什么意思啊(Breakdown的定义)

breakdown是什么意思啊(Breakdown的定义)

本文目录Breakdown的定义breakdown什么意思mental breakdown是什么意思Breakdown在商务英语中是什么意思breakdowns中文是什么意思流行音乐编曲中breakdown,drop的中文意思是什么Brea

2025年2月23日 02:30

swings是什么意思(swing是什么意思英语)

swings是什么意思(swing是什么意思英语)

本文目录swing是什么意思英语“swing”是什么意思Swings是什么意思swing是什么意思英语swing的意思:摇摆;改变。swing,英[swɪŋ],美[swɪŋ]n.摇摆;改变;冲力;秋千v.摇摆;旋转;动摇形容词:swingy

2025年2月19日 12:10

ppt制作幻灯片(PPT幻灯片怎么制作表格怎么设计图片怎么处理出想要的效果)

ppt制作幻灯片(PPT幻灯片怎么制作表格怎么设计图片怎么处理出想要的效果)

本文目录PPT幻灯片怎么制作表格怎么设计图片怎么处理出想要的效果如何用ppt制作幻灯片ppt怎么制作幻灯片PPT幻灯片怎么制作表格怎么设计图片怎么处理出想要的效果Focusky是一款简单易用的幻灯片制作工具,它操作简单,功能齐全,可以轻松做

2025年2月22日 22:20

abap开发实例(SAP abap开发现在有一张内表ITAB里面有两个字段A和B数据如下:)

abap开发实例(SAP abap开发现在有一张内表ITAB里面有两个字段A和B数据如下:)

本文目录SAP abap开发现在有一张内表ITAB里面有两个字段A和B数据如下:求《实战SAP程序开发——从实例学SAP ABAP编程》电子书SAP abap开发现在有一张内表ITAB里面有两个字段A和B数据如下:data: l_lines

2025年3月11日 18:20

coreldraw怎么读中文(coreldraw怎么读)

coreldraw怎么读中文(coreldraw怎么读)

本文目录coreldraw怎么读coreldraw x4怎么读CorelDRAW怎么读CorelDRAW用中文怎么读coreldraw 怎么读CorelDraw读什么,是什么意思CorelDRAW中文怎么说“coreldraw”怎么读cor

2025年2月18日 04:00

css后代选择器(css后代选择器和子选择器的区别介绍)

css后代选择器(css后代选择器和子选择器的区别介绍)

本文目录css后代选择器和子选择器的区别介绍css后代选择器有哪些常见css选择器有哪些在css中一般来讲后代选择器比子代选择器所修饰的范围广对吗css选择器有哪些,哪些可以继承css后代选择器和子选择器的区别介绍css后代选择器和子选择器

2025年2月9日 00:50

elemtype data是什么意思(typedef struct LNode { ElemType data; struct LNode *next; } LNode, *LinkList 是什么意思)

elemtype data是什么意思(typedef struct LNode { ElemType data; struct LNode *next; } LNode, *LinkList 是什么意思)

本文目录typedef struct LNode { ElemType data; struct LNode *next; } LNode, *LinkList 是什么意思关于c语言,谢谢解答请问typedef struct {elemty

2025年3月5日 23:40

java swing包(java的Swing是轻量级组件,轻量级组件是什么意思)

java swing包(java的Swing是轻量级组件,轻量级组件是什么意思)

本文目录java的Swing是轻量级组件,轻量级组件是什么意思刚学java,对于javax.swing包中的swing,不知道他是什么,我就知道是使用它设计图形Java编程中,Swing包中的组件处理事件时,下面()是正确的(选择一项)ja

2025年2月27日 09:20

sequence(identity 和sequence的区别)

sequence(identity 和sequence的区别)

本文目录identity 和sequence的区别sequence是什么意思oracle sequence 干嘛用的stacking sequence是什么意思sequence用汉语咋读consequence中文怎么读identity 和s

2025年3月1日 02:50

matches是什么意思中文(Match的中文是什么意思)

matches是什么意思中文(Match的中文是什么意思)

本文目录Match的中文是什么意思matches方法有什么功能matches是什么意思中文matches的中文怎么写matches的意思Match的中文是什么意思match 英 第三人称单数:matches 复数:matches 现在分词:

2025年3月20日 02:00

网站测试报告(网站测试是什么)

网站测试报告(网站测试是什么)

本文目录网站测试是什么web网站后台管理系统的测试报告怎么写中科院相关网站的测试报告指出,防蓝光并不是智商税,其原因是什么网站测试工作都需要做什么什么机构/单位可以出网站安全检测报告淘宝网网上购物测试报告怎么写网络测试报告文档的模版网站测试

2025年3月18日 13:40

access2007教程(数据库应用Access2007实例教程的内容简介)

access2007教程(数据库应用Access2007实例教程的内容简介)

本文目录数据库应用Access2007实例教程的内容简介如何修复Access数据库_Access数据库教程数据库应用Access2007实例教程的目录数据库应用Access2007实例教程的内容简介Microsoft Access 2007

2025年3月1日 16:50

outlined(transistor+outline是什么意思)

outlined(transistor+outline是什么意思)

本文目录transistor+outline是什么意思outline-level是什么意思transistor+outline是什么意思transistor outline英 第三人称单数:outlines 复数:outlines

2025年2月12日 20:10

ln的公式大全(Ln的运算法则是什么计算的)

ln的公式大全(Ln的运算法则是什么计算的)

本文目录Ln的运算法则是什么计算的ln公式是什么呀ln的公式有哪些Ln的运算法则是什么计算的Ln的运算法则:(1)ln(MN)=lnM +lnN(2)ln(M/N)=lnM-lnN(3)ln(M^n)=nlnM(4)ln1=0(5)lne=

2025年3月18日 15:00

开源操作系统(windows是开源系统还是封闭系统)

开源操作系统(windows是开源系统还是封闭系统)

本文目录windows是开源系统还是封闭系统开源操作系统是什么意思华为发布开源操作系统欧拉,这意味着什么开源的操作系统有哪些华为宣布捐赠欧拉开源操作系统,你如何看待这件事华为在全联接大会上正式发布了开源操作系统欧拉,该系统的定位是什么华为宣

2025年3月18日 04:20

scrapped是什么意思(acceptable是什么意思)

scrapped是什么意思(acceptable是什么意思)

本文目录acceptable是什么意思shapeofmyheart是什么意思scrapped是什么意思,报废的翻译acceptable是什么意思一、读音: 二、意思是合意的;受欢迎的。三、例句If these terms are not a

2025年3月20日 21:50

reduce的名词形式(reduce relax ease区别)

reduce的名词形式(reduce relax ease区别)

本文目录reduce relax ease区别decrease和reduce有什么区别求大神帮助reduce decrease descend 区别reduce、diminish、eliminate、decrease的区别increase和

2025年3月6日 02:10

json文件用什么软件打开(json格式怎么打开)

json文件用什么软件打开(json格式怎么打开)

本文目录json格式怎么打开该文件没有与之关联的程序来执行该操作请安装一个程序,或者,如果已安装程序,请在“默认程序”json文件怎么打开json格式怎么打开打开json格式的文件的具体操作步骤如下:操作设备:联想拯救者Y9000。操作系统

2025年3月4日 06:20

c语言函数调用方式(C语言如何调用函数)

c语言函数调用方式(C语言如何调用函数)

本文目录C语言如何调用函数C语言中什么叫调用函数为什么函数和函数之间是调用关系c语言如何实现函数的调用c语言中函数的调用方法c语言中怎么调用自己定义的函数C语言中怎样调用函数c语言中函数调用有三种方法,能帮忙各举个例子吗C语言中怎样调用函数

2025年2月17日 14:40

近期文章

本站热文

harbor,port,pier的区别?谁能解释“harbour“(港口)与“pier“(码头)的区别
2025-02-22 17:40:03 浏览:18
ibatis foreach(ibatis 批量update操作)
2025-02-10 23:40:06 浏览:7
endless rain(endless rain表达什么情感)
2025-02-14 06:00:02 浏览:6
标签列表

热门搜索