单利 java_Java设计模式-单利模式

单例模式

作为对象的创建模式,单例模式确保其某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。单例模式有以下特点:

1、单例类只能有一个实例

2、单例类必须自己创建自己的唯一实例

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

下面看一下单例模式的三种写法,除了这三种写法,静态内部类的方式、静态代码块的方式、enum枚举的方式也都可以,不过异曲同工,这三种方式就不写了。

首先声明就是 在我们项目工程中 我们完全不用使用懒汉式 因为有锁使用的地方就有效率低的存在;

饿汉式

顾名思义,饿汉式,就是使用类的时候不管用的是不是类中的单例部分,都直接创建出单例类,看一下饿汉式的写法:

public classSingleEager {public static SingleEager se = newSingleEager();public staticSingleEager getInstance()

{returnse;

}

}

这就是饿汉式单例模式的写法,也是一种比较常见的写法。这种写法会不会造成竞争,引发线程安全问题呢?答案是不会。

可能有人会觉得奇怪:第3行,CPU执行线程A,实例化一个EagerSingleton,没有实例化完,CPU就从线程A切换到线程B了,线程B此时也实例化这个EagerSingleton,然后EagerSingleton被实例化出来了两次,有两份内存地址,不就有线程安全问题了吗?

没关系,我们完全不需要担心这个问题,JDK已经帮我们想到了。Java虚拟机2:Java内存区域及对象,文中可以看一下对象创建这一部分,没有写得很详细,其实就是"虚拟机采用了CAS配上失败重试的方式保证更新更新操作的原子性和TLAB两种方式来解决这个问题"。

懒汉式

同样,顾名思义,这个人比较懒,只有当单例类用到的时候才会去创建这个单例类,看一下懒汉式的写法:

public classLazySingleton

{private static LazySingleton instance = null;privateLazySingleton()

{

}public staticLazySingleton getInstance()

{if (instance == null)

instance= newLazySingleton();returninstance;

}

}

这种写法基本不用,因为这是一种线程非安全的写法。试想,线程A初次调用getInstance()方法,代码走到第12行,线程此时切换到线程B,线程B走到12行,看到instance是null,就new了一个LazySingleton出来,这时切换回线程A,线程A继续走,也new了一个LazySingleton出来。这样,单例类LazySingleton在内存中就有两份引用了,这就违背了单例模式的本意了。

可能有人会想,CPU分的时间片再短也不至于getInstance()方法只执行一个判断就切换线程了吧?问题是,万一线程A调用LazySingleton.getInstance()之前已经执行过别的代码了呢,走到12行的时候刚好时间片到了,也是很正常的。

双检锁【其实这个地方叫做 带锁的双检懒汉式单利模式】

既然懒汉式是非线程安全的,那就要改进它。最直接的想法是,给getInstance方法加锁不就好了,但是我们不需要给方法全部加锁啊,只需要给方法的一部分加锁就好了。

双检的目的是为了提高效率,当第一次线程创建了实例对象后,后边进入的线程通过判断第一个是否为null,可以直接不用走入加锁的代码区;

基于这个考虑,引入了双检锁(Double Check Lock,简称DCL)的写法:

public classDoubleCheckLockSingleton

{private static DoubleCheckLockSingleton instance = null;privateDoubleCheckLockSingleton()

{

}public staticDoubleCheckLockSingleton getInstance()

{if (instance == null)

{synchronized (DoubleCheckLockSingleton.class)

{if (instance == null)

instance= newDoubleCheckLockSingleton();

}

}returninstance;

}

}

双检锁的写法是不是线程安全的呢?是的,至于为什么,不妨以分析懒汉式写法的方式分析一下双检锁的写法。

线程A初次调用DoubleCheckLockSingleton.getInstance()方法,走12行,判断instance为null,进入同步代码块,此时线程切换到线程B,线程B调用DoubleCheckLockSingleton.getInstance()方法,由于同步代码块外面的代码还是异步执行的,所以线程B走12行,判断instance为null,等待锁。结果就是线程A实例化出了一个DoubleCheckLockSingleton,释放锁,线程B获得锁进入同步代码块,判断此时instance不为null了,并不实例化DoubleCheckLockSingleton。这样,单例类就保证了在内存中只存在一份。

单例模式在Java中的应用及解读

Runtime是一个典型的例子,看下JDK API对于这个类的解释"每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接,可以通过getRuntime方法获取当前运行时。应用程序不能创建自己的Runtime类实例。",这段话,有两点很重要:

1、每个应用程序都有一个Runtime类实例

2、应用程序不能创建自己的Runtime类实例

只有一个、不能自己创建,是不是典型的单例模式?看一下,Runtime类的写法:

f2940af480e1b4b65ede0eee02de2ab9.png

public class Runtime {

private static Runtime currentRuntime = new Runtime(); //使用饿汉式

/**

* Returns the runtime object associated with the current Java application.

* Most of the methods of class Runtime are instance

* methods and must be invoked with respect to the current runtime object.

*

* @return the Runtime object associated with the current

* Java application.

*/

public static Runtime getRuntime() {

return currentRuntime;

}

/** Don‘t let anyone else instantiate this class */

private Runtime() {}

...

}

f2940af480e1b4b65ede0eee02de2ab9.png

后面的就不黏贴了,到这里已经足够了,看到Runtime使用getRuntime()方法并让构造方法私有保证程序中只有一个Runtime实例且Runtime实例不可以被用户创建。

单例模式的好处

作为一种重要的设计模式,单例模式的好处有:

1、控制资源的使用,通过线程同步来控制资源的并发访问

2、控制实例的产生,以达到节约资源的目的

3、控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信

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

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

相关文章

java定义private_java9开始——接口中可以定义private私有方法

在传统的Java编程中,被广为人知的一个知识点是:java Interface接口中不能定义private私有方法。只允许我们定义public访问权限的方法、抽象方法或静态方法。但是从Java 9 开始,Interface 接口中允许定义私有方法和私有静态方法。下面我们就来…

链表每k个反转 java_K 个一组翻转链表

leetcode第25题(困难)问题描述给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。示例:给…

phpcms上传php,phpcms如何上传视频

phpcms如何上传视频?phpcms-v9上传视频文件时的解决方案1.不建议直接在后台上传视频文件,因为视频文件一般都比较大,直接上传影响带宽;可先通过ftp工具将视频文件上传到指定目录,然后再后台引入视频文件的地址即可2.如…

护卫神怎么重启php,护卫神·主机大师如何开启php_opcache_护卫神

护卫神主机大师支持5.5至7.3这几个版本开启php_opcache扩展。一,先打开护卫神主机大师面板-常用操作-打开软件目录二,打开phpweb目录,找到要开启opcache的php版本,比如我这里要在php5.5中开启,进入php55目录&#xff0…

java 去除 quot,JAVA去除web页面传入后台的特殊字符工具类 | 学步园

package www.tmzskj.com.utils;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.junit.Test;/*** 功能 过滤特殊字符,清除掉所有特殊字符* regEx 为要清除的字符* author admin**/public class StringFilterTest {public static String …

matlab中的terminator模块,2.2 Ground 及 Terminator模块

课时:117节课时长:20.1小时课级:中级提高simulink是matlab中的一种可视化仿真工具, 是一种基于matlab的框图设计环境,是实现动态系统建模、仿真和分析的一个软件包,被广泛应用于线性系统、非线性系统、数字…

oracle判断数据出现交叉,Oracle!你必须要知道的Knowledge points(一)

一、入门oracle有四个用户,分别为sys、system、sysman和scott,其中sys是oracle权限最高的用户,类似于Linux系统的root,scott是示例用户,上课就以这个用户里的三张员工表empno、dept、salgrade作为示例来授课。启动服务1. 快捷键ct…

php上传中文图片,用PHP处理图片文件的上传

这篇文章主要介绍了关于用PHP处理图片文件的上传&#xff0c;有着一定的参考价值&#xff0c;现在分享给大家&#xff0c;有需要的朋友可以参考一下1.html文件form表单注意。enctype属性代码&#xff1a;<?php require(../../public/common/config.php);$sqlClass "s…

linux中的进程权限是,Linux中权限,进程,服务的简单操作

1.权限存在意义- rw-r-r-r-- 1 root root 216 May 12 2017 /mnt/rht[1] [2] [3] [4] [5] [6] [7] [8][1] 文件类型-普通文件d目录l软链接ssocketc文件权限[2] 文件权限rw-|r--|r--u g ouuserggroupoo…

linux 运行eclipse,解决Linux下Eclipse启动错误

下载Eclipse后一打开就报错&#xff1a;JVM terminated. Exit code-1-Xms40m-Xmx256m-XX:MaxPermSize256m-Djava.class.path/usr/local/eclipse/plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar-os linux-ws gtk-arch x86-showsplash /usr/local/eclipse//pl…

c语言stm32串口控制单片机,实用STM32的串口控制平台的实现

假设我要编写一个自己的指令脚本&#xff0c; 来读取MCU的关键信息&#xff0c;关键字为mcu&#xff0c; 文件命名为shell_mcu.c&#xff1b; 当输入“mcu rd 0”时显示MCU的FLASH大小&#xff0c;输入“mcu rd 1”时读取MCU的唯一ID信息。shell_mcu.c源代码&#xff1a;/*****…

time_t c语言 2038,什么是2038问题?

什么是2038问题不知道你有没有听过2038问题?无论你是否听过&#xff0c;本文将带你认识什么是2038问题。Unix时间戳定义为从格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。而在C语言中&#xff0c;常用time_t来表示。举个例子…

c 语言 readline,如何用C实现一个readLine()函数- 该函数每次读入文本文件的一行并打印到屏幕...

如何用C实现一个readLine()函数- 该函数每次读入文本文件的一行并打印到屏幕(2012-04-13 00:23:41)标签&#xff1a;打印文本文件如何杂谈如何用C实现一个readLine()函数? 该函数每次读入文本文件的一行并打印到屏幕以前看到过这方面的讨论http://bbs.chinaunix.net/viewthrea…

c4droid语言游戏,c4droid手机编程软件下载

c4droid可以说是手机端最好的编程软件&#xff0c;没有之一&#xff0c;软件可以帮助大家在手机上进行编写C代码,让各位程序员们随时随地都能编程。操纵简单&#xff0c;功能强大。c4droid软件介绍c4droid是款Android设备上的C/C程序编译器&#xff0c;默认以tcc(tiny c compil…

创业冲突的五种解决方法是_不会说话,不懂处理人际冲突怎么办?《沟通的艺术》5步教会你...

关注“夏娃蓝空间”&#xff0c;陪你成长为更好的自己。想要良好地解决冲突&#xff0c;一定要有“这是我们两个人共同的事”的态度。今年夏天最热门的电视剧非《三十而已》莫属了&#xff0c;而撑起了这部剧的流量的广大观众&#xff0c;基本都是集中在逐步靠近中青年阶段的90…

android gsensor 坐标,MTK Android G sensor 原理,配置,调试

原理图&#xff1a;g_sensor的驱动目录在mediatek/custom/common/kernel/accelerometer下。一、g_sensor 的移植步骤1、在ProjectConfig.mk中配置相关的g_sensor例如 CUSTOM_KERNEL_ACCELEROMETER kxtf92、在mediatek/custom/common/kernel/accelerometer目录中添加 g_sensor的…

网贷大数据什么时候会好_如果人类把地球钻穿了,会发生什么?大数据分析告诉你多可怕...

很多科研人员在做实验的时候&#xff0c;少不了被旁人嘲笑或者蔑视的情况&#xff0c;因为常人往往是无法理解他们的想法的。例如曾经就有科研人员想要对地球进行钻探&#xff0c;看看能够在地表上钻多深&#xff0c;是否能够将地球给钻穿了。很多人都会认为这种做法没有意义而…

android h5 有广告,那些H5在Android上显示的丧心病狂的坑

首先得强调一下&#xff0c;H5和移动设备的交互遇到的问题真的是各种丧心病狂&#xff01;&#xff01;但是本主依然还是耐着极大的兴致(无奈)的做了下去。H5页面在Android或者IOS上运行出现问题(这里的运行指的是h5的页面运行在App里的webview里)&#xff0c;测试人员或者上级…

小米9android q测试版,基于Android Q的MIUI来了 小米9尝鲜

01基于Android Q的MIUI来了中关村在线消息&#xff1a;谷歌在今年五月份发布了最新的Android Q系统&#xff0c;虽然很多国产手机还没有升级到Android P&#xff0c;但是还是有不少厂家开始对旗下的手机升级到最新的Android Q系统&#xff0c;根据小米最新的官方的消息&#xf…

android layerlist bitmap,android shape类似的 另一个 高端用法:layer-list

android shape类似的 另一个 高端用法&#xff1a;layer-list&#xff1a;简介&#xff1a;将多个图片或上面两种效果按照顺序层叠起来” 《?xml version"1.0" encoding"utf-8"?>《layer-listxmlns:android"http://schemas.android.com/apk/res/…