java中的单例模式

一、描述

单例模式就是程序中一个类只能有一个对象实例

举个例子:

//引出单例模式,一个类中只能由一个对象实例
public class Singleton1 {private static Singleton1 instance = new Singleton1();//通过这个方法来获取实例public static Singleton1 getInstance() {return instance;}//把构造方法设置私有,防止创建多个线程private Singleton1() {}
}
public class  Test1{public static void main(String[] args) {Singleton1 s1 = new Singleton1();}
}

这样写Test1类中Singleton1 s1 = new Singleton1();会报错,因为我们在Singleton1中把构造方法设置了私有

二、单例模式分类

1、饿汉模式

开始我就先给创建出这个实例并且赋值分配空间,代码如下:

public class Singleton1 {private static Singleton1 instance = new Singleton1();//通过这个方法来获取实例public static Singleton1 getInstance() {return instance;}
}

2、懒汉模式

在开始不创建这个实例,在第一次调用这个类的时候在创建实例,这样随用随分配空间,代码如下

public class Singleton2 {private static Singleton2 instance = null;//通过这个方法来获取实例public static Singleton2 getInstance() {if(instance==null){instance=new Singleton2();}return instance;}//把构造方法设置私有,防止创建多个线程private Singleton2() {}
}

三、懒汉模式的代码问题

问题一

这是多线程,如果有两个线程分别是a和b,a开始调用这个类的时候instance==null,开始创建实例instance,同时b线程在a还有没有创建完instance的时候也开始调用这个类,判断条件是同样instance==null,也开始创建实例当两个线程都执行完,就创建了两个实例,违背了单例模式,这是bug!!!

问题一解决方案

其实很简单,我们只需要引入锁就可以,保证判断instance==null和new的对象是一起执行或者都不执行就可以了,代码如下:

public class soltion1 {private static soltion1 instance = null;static Object object=new Object();//通过这个方法来获取实例public static soltion1 getInstance() {synchronized (object){if(instance==null){instance=new soltion1();}}return instance;}//把构造方法设置私有,防止创建多个线程private soltion1() {}
}

有个新的问题,如果a线程创建了instance,但是以后的线程都要加锁,这就造成了cpu创建锁的负担,这是问题二

问题二解决方案

我们只要保证instance为空的时候进来是需要加锁的,别的时候再进来就不用加锁了

public class soltion1 {private static soltion1 instance = null;static Object object=new Object();//通过这个方法来获取实例public static soltion1 getInstance() {if(instance==null){//这个if是判断instance是否为空,synchronized (object){if(instance==null){//这个if是判断时候new新的对象instance=new soltion1();}}}return instance;}//把构造方法设置私有,防止创建多个线程private soltion1() {}
}

到这里我们已经解决了大部分问题了,但是new创建对象的时候是有三部曲:

  1. 申请内存空间
  2. 在内存空间上构造对象
  3. 把内存的地址,赋值给instance引用

上述描述这是问题三 

问题三解决方案

加volatile,保证instance再修改时不会出现指令重排序情况

private volatile static soltion1 instance = null;

总结

public class soltion1 {private volatile static soltion1 instance = null;static Object object=new Object();//通过这个方法来获取实例public static soltion1 getInstance() {if(instance==null){//这个if是判断instance是否为空,synchronized (object){if(instance==null){//这个if是判断时候new新的对象instance=new soltion1();}}}return instance;}//把构造方法设置私有,防止创建多个线程private soltion1() {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/573154.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手写SpringBoot(一)之简易版SpringBoot

手写SpringBoot&#xff08;一&#xff09;之简易版SpringBoot 添加依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"…

数据结构——排序算法

1、排序的概念 排序是指的是将一组数据&#xff08;如数字、单词、记录等&#xff09;按照某种特定的顺序&#xff08;升序或降序&#xff09;进行排列的过程。排序算法是实现排序的程序或方法&#xff0c;它们在软件开发和数据处理中扮演着至关重要的角色。 排序算法可以根据…

强化基础-Java-泛型

什么是泛型&#xff1f; 泛型其实就参数化类型&#xff0c;也就是说这个类型类似一个变量是可变的。 为什么会有泛型&#xff1f; 在没有泛型之前&#xff0c;java中是通过Object来实现泛型的功能。但是这样做有下面两个缺陷&#xff1a; 1 获取值的时候必须进行强转 2 没有…

[BT]BUUCTF刷题第9天(3.27)

第9天&#xff08;共2题&#xff09; [护网杯 2018]easy_tornado 打开网站就是三个txt文件 /flag.txt flag in /fllllllllllllag/welcome.txt render/hints.txt md5(cookie_secretmd5(filename))当点进flag.txt时&#xff0c;url变为 http://b9e52e06-e591-46ad-953e-7e8c5f…

银行卡的分类

银行卡是银行账户的一种体现形式&#xff0c;它是由银行机构发行的具有消费信用、转账结算、存取现金等全部或部分功能作为结算支付工具的各类卡的统称。 &#xff08;1&#xff09;按是否具有授信额度分类 ①借记卡&#xff1a;借记卡是指发卡银行向申请人签发的&#xff0c;没…

第十一章:位运算符与位运算

文章目录 第十一章&#xff1a;位运算符与位运算1.按位与运算&#xff1a;&2.按位或运算&#xff1a;|3.按位异或运算&#xff1a;^4.取反运算符&#xff1a;~5.左移运算符&#xff1a;<<6.右移运算符&#xff1a;>>总结 第十一章&#xff1a;位运算符与位运算…

动态内存操作函数使用过程中会遇见的问题

越界访问 首先我们上一个代码&#xff0c;看看这个的代码的问题 这个代码的问题显而易见 &#xff0c;就是在循环里面&#xff0c;产生了越界访问的问题&#xff0c;这里你开辟了10个整形空间&#xff0c;但是从0-10一共是11个整形空间。导致访问不合法的空间&#xff0c;从而…

Cy3-PEG-NH2 Cy3-聚乙二醇-氨基 磷脂PEG花菁Cy3

产品名称 Cy3-PEG-NH2 目录号 410502 中文名称 Cy3-聚乙二醇-氨基 英文名称 Cy3-PEG-NH2 Cy3-PEG-Amine 分子量 2000 溶解度 溶于氯仿等有机溶剂 存储条件 -20冷冻避光 保存时间 一年 Ex/Em(nm) 550/570 其它分子量 1000 3400 5000 10000 结构 花氰染料Cyanine,常应用…

记一次由gzip引起的nginx转发事故

故事背景 书接前几篇文章&#xff0c;仍然是交付甲方遇到的一个特殊诉求&#xff0c;从而引发了本期的事故。甲方的诉求是前端的请求过来&#xff0c;需要加密&#xff0c;但是要经过waf&#xff0c;必须要求是请求明文&#xff0c;那就要在waf和nginx之间做一个解密前置应用处…

搜索插入位置-java

题目描述 : 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。 思路分析: 这段代码的解题思想是利用二分查找的方法在…

MySql实战--事务到底是隔离的还是不隔离的

第3篇文章和你讲事务隔离级别的时候提到过&#xff0c;如果是可重复读隔离级别&#xff0c;事务T启动的时候会创建一个视图read-view&#xff0c;之后事务T执行期间&#xff0c;即使有其他事务修改了数据&#xff0c;事务T看到的仍然跟在启动时看到的一样。也就是说&#xff0c…

深入探讨分布式ID生成方案

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…