Java设计模式之单例模式 通俗易懂 超详细 【内含案例】
单例模式
推荐 Java 常见面试题
什么是单例模式 ?
确保程序中一个类只能被实例化一次,实现这种功能就叫单例模式
单例模式的好处是什么 ?
- 方便控制对象
- 节省资源减少浪费
怎么实现单例模式 ?
- 构造私有化
- 调用静态方法返回实例
- 确保对象的实例只有一个
常见的单例模式有哪些 ?
- 饿汉式
把对象创建好,需要使用的时候直接用就行
饥肠辘辘 非常着急
- 懒汉式
- 由于饿汉式容易浪费资源,比如类里 有
public static
修饰的一个方法test()
,即可不创建实例就可访问到懒
不到万不得已不创建实例,什么时候用什么时候创建
懒汉式的缺点呢 ?
线程不安全 但是可以控制
如何控制,下面会讲
代码实现饿汉式
创建
Singleton.java
类
public class Singleton1 {
public static final Singleton1 INSTANCE = new Singleton1();
//构造方法私有化
private Singleton1(){
}
//get方式获取对象
public static Singleton1 getInstance(){
return INSTANCE;
}
}
创建
TestSingleton.java
类
public class TestSingleton{
public static void main(String[] args) {
Singleton1 st1 = Singleton1.INSTANCE;
Singleton1 st2 = Singleton1.getInstance();
//return true
System.out.println(st1.hashCode() == st2.hashCode());
//return true
System.out.println(st1 == st2);
}
}
代码实现懒汉式
创建
Singleton2.java
类
public class Singleton2 {
private static Singleton2 INSTANCE;
//构造方法私有化
private Singleton2(){
}
//get方式获取对象
public static Singleton2 getInstance(){
if (INSTANCE == null) {
INSTANCE = new Singleton2();
}
return INSTANCE;
}
}
x修改
TestSingleton.java
类
Singleton2 a = Singleton2.getInstance();
Singleton2 b = Singleton2.getInstance();
//ture
System.out.println(a == b);
注意: 再有的情况下懒汉式线程不安全比如多线程
举例说明 线程不安全
修改
Singleton2.java
类
public static Singleton2 getInstance(){
if (INSTANCE == null) {
try {
Thread.sleep((int) Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton2();
}
return INSTANCE;
}
修改
TestSingleton.java
类
Callable<Singleton2> c = new Callable<Singleton2>() {
@Override
public Singleton2 call() throws Exception {
return Singleton2.getInstance();
}
};
//创建两个线程池
ExecutorService es = Executors.newFixedThreadPool(2);
Future<Singleton2> f1 = es.submit(c);
Future<Singleton2> f2 = es.submit(c);
Singleton2 a = f1.get();
Singleton2 b = f2.get();
/**
* 有可能两种情况
* 1. 判断是否一致:false
* 2. 判断是否一致:true
*/
System.out.println("判断是否一致:" + (a == b));
为什么会这样呢 ?
- 因为第一个线程 if (INSTANCE == null) 进去之后触发 sleep() 线程休眠
- 第二个线程就紧跟着 if (INSTANCE == null) 这时 INSTANCE 还是等于null,随后进入线程休眠
- 这样他两个都创建了实例,一共创建两次所以导致线程不安全
怎么解决线程不安全 ?
解决
懒汉式
线程不安全的方法
- 使用
synchronized
同步锁- 使用静态内部类
使用 synchronized
同步锁
修改
Singleton2.java
类
public static Singleton2 getInstance(){
//提高效率 已经new过后不需要再等着资源
if (INSTANCE == null) {
//可以使用同步锁 完成线程安全
synchronized (Singleton1.class) {
if (INSTANCE == null) {
try {
Thread.sleep((int) Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton2();
}
}
}
return INSTANCE;
}
- 再次运行
TestSingleton.java
测试 就会返回true
- 但是还是有一个问题,第一个线程已经创建好了,第二个线程还需要再次进入
synchronized
块等待资源的控制权.可以在外面加上if
判断INSTANCE == null
即可提高效率
使用静态内部类
因使用
synchronized
同步锁,代码看起来不雅观,所以可以使用静态内部类,达到线程安全
修改
Singleton2.java
类
public class Singleton2 {
//构造私有化
private Singleton2(){
}
//在内部类被加载时,才创建
//静态内部类 不会随着外部类加载,初始化 它是一个独立的 当用这个类时才会加载初始化
//在内部类加载和初始化,所以线程是安全的
private static class Inner{
private static final Singleton2 INSTANCE = new Singleton2();
}
//get 方式获取静态内部类的INSTANCE
public static Singleton2 getInstance(){
return Inner.INSTANCE;
}
}
小结
并不能说明 懒汉式 要强于 饿汉式,可以根据项目需求,来使用其中一种模式
再次推荐 保你面试必过的 java面试题
本文就先说到这里,有问题欢迎留言讨论
Java设计模式之单例模式 通俗易懂 超详细 【内含案例】的更多相关文章
- java 设计模式之单例模式
-------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...
- 折腾Java设计模式之单例模式
博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...
- Java设计模式之单例模式(七种写法)
Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...
- Java 设计模式之单例模式(一)
原文地址:Java 设计模式之单例模式(一) 博客地址:http://www.extlight.com 一.背景 没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴. 本篇内容为 Java ...
- java设计模式1——单例模式
java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...
- Java中的三大特性 - 超详细篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的三大特性 - 超详细篇>,希望对大家有帮助,谢谢 这一节的内容可能有点多,大家可以选择性的来看 简介 Java的三大特性:封装.继 ...
- java设计模式之单例模式你真的会了吗?(懒汉式篇)
java设计模式之单例模式你真的会了吗?(懒汉式篇) 一.什么是单例模式? 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供 ...
- java设计模式之单例模式(七种方法)
单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- java设计模式- (1)单例模式
参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...
随机推荐
- hdu4135题解 容斥
Problem Description Given a number N, you are asked to count the number of integers between A and B ...
- 一款.NET开源的i茅台自动预约小助手
前言 今天大姚给大家分享一款.NET开源.基于WPF实现的i茅台APP接口自动化每日自动预约(抢茅台)小助手:HyggeImaotai. 项目介绍 该项目通过接口自动化模拟i茅台APP实现每日自动预约 ...
- Linux系统的硬件信息
查看Linux系统的硬件信息 [1]查看内核信息 uname 用于显示系统的内核信息 option -s:显示内核名称 -r:显示内核版本 [root@bogon /]# uname -a Linux ...
- ComfyUI进阶篇:ComfyUI核心节点(一)
ComfyUI进阶篇:ComfyUI核心节点(一) 前言: 学习ComfyUI是一场持久战.当你掌握了ComfyUI的安装和运行之后,会发现大量五花八门的节点.面对各种各样的工作流和复杂的节点种类,可 ...
- 2024秋招字节跳动朝夕光年UE4客户端开发实习生岗笔试题目
20240117更新 2024年秋招笔试题目,没想到时隔几个月字节跳动游戏业务就要寄了,本文仅供参考,请大佬多多指教 Q1字符串处理 Q2 杯子问题 桌子上有4109+1个饮料杯,这些饮料杯的编号依次 ...
- CGI、FastCGI和PHP-FPM区别和关系详解
在搭建 LAMP/LNMP 服务器时,会经常遇到 PHP-FPM.FastCGI和CGI 这几个概念.如果对它们一知半解,很难搭建出高性能的服务器.接下来我们就以图形方式,解释这些概念之间的关系. 1 ...
- 操作系统|C语言模拟实现首次适应和最佳适应两种内存分配算法以及内存回收
两种算法 首次适应 首次适应算法从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间.为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到 ...
- JavaScript一天一个算法题~持续更新中。。。。。
1,数组去重 i.暴力去重 思路:建一个空数组,通过判断原数组的元素是否在空数组内,如果在,不放入,不在,放入空数组. function clearCommnetArray(array){ let a ...
- Java学习_重置版一:Java语言基础之数据和标识符等
第一:关键字 (1)被Java语言赋予特定含义的单词 (2)特点:全部小写. (3)注意事项: A:goto和const作为保留字存在. B:类似于Notepad++这 ...
- ngnix简介和基础
一.Nginx简介 Nginx 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP代理服务器 是一个模块化软件 [1].安装nginx 使用源码包编译安装 cd /opt ...