单例模式

什么是单例模式 ?

确保程序中一个类只能被实例化一次,实现这种功能就叫单例模式

单例模式的好处是什么 ?

方便控制对象

节省资源减少浪费

怎么实现单例模式 ?

构造私有化

调用静态方法返回实例

确保对象的实例只有一个

常见的单例模式有哪些 ?

饿汉式

把对象创建好,需要使用的时候直接用就行饥肠辘辘 非常着急

懒汉式

由于饿汉式容易浪费资源,比如类里 有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 c = new Callable() {

@Override

public Singleton2 call() throws Exception {

return Singleton2.getInstance();

}

};

//创建两个线程池

ExecutorService es = Executors.newFixedThreadPool(2);

Future f1 = es.submit(c);

Future 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设计模式之单例模式 通俗易懂 超详细 【内含案例】相关推荐

  1. java 影子实例_java设计模式(四)--单例模式

    Singleton最熟悉不过了,下面学习单例模式.转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Singleton)是一种常用的设计模式.在Jav ...

  2. 3种设计模式java小程序_Java设计模式之单例模式(3种实现方式)

    饿汉模式 public class Singleton {//实例化private static Singleton instance=new Singleton();private Singleto ...

  3. c语言指针用法及实际应用详解,通俗易懂超详细

    c语言指针用法及实际应用详解,通俗易懂超详细! \\\插播一条:文章末尾有惊喜哟~/// 今天给大家来讲解一下指针. 我会由浅到深,最后联合实际应用讲解,让大家学会指针的同时,知道大佬们都用指针来干嘛 ...

  4. java单例模式的七种写法_Java设计模式之单例模式的七种写法

    什么是单例模式? 单例模式是一种常见的设计模式,单例模式的写法有很多种,这里主要介绍三种: 懒汉式单例模式.饿汉式单例模式.登记式单例 . 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类 ...

  5. java单例设计模式_Java设计模式之单例模式详解

    在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...

  6. java connection 单例_Java设计模式之单例模式详解

    Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...

  7. java+单例+恶汉_Java设计模式之单例模式(恶汉式和懒汉式)

    /** 单例模式:* 饿汉式:类一加载就创建对象* 懒汉式:用的时候,才去创建对象* 面试题:单例模式的思想是什么?写一个代码体现(我们最好写懒汉式的单例模式给面 /* * 单例模式: *       ...

  8. Docker02 狂神Docker视频学习笔记 :【狂神说Java 哔哩哔哩】Docker最新超详细版教程通俗易懂

    目录 0. 视频源 0. 学习网址 基础篇 1. Docker概述 1.1 Docker为什么出现? 1.2 Docker历史 1.3 Docker能干什么 2. Docker安装 2.1 Docke ...

  9. java设计模式在线视频_Java设计模式之单例模式视频课程

    一.概述 多例模式(Multiton  Pattern),这种设计模式也属于对象创建型模式,本质上就是单例模式的推广 定义: 一个类有多个实例且由类本身创建和管理自己的实例,并向外部提供访问点. 二. ...

最新文章

  1. java 图片传输方式_Java图像传输方法
  2. cocos2d-x 3.2 listview scorllview 等容器在小米华为等部分手机显示泛白解决
  3. 如何修改以前登录过的共享文件夹的用户名和密码以及查看或删除浏览器里保存的密码...
  4. C#使用多态求方形面积周长和圆的面积周长
  5. thinkphp-where-数组条件-普通查询
  6. g团最多的服务器,魔兽世界怀旧服:田园服务器的G团 打本就像白送装备 最后还分金...
  7. mysql数据库实现修改密码代码_MySQL数据库的更改密码(附源代码)
  8. POJ 3080 Blue Jeans (KMP)
  9. 用typedef给结构体一个别名
  10. 全球著名编程大赛地址
  11. php从文件中查找内容
  12. 数据库及基本表的建立
  13. 有道云笔记 markdown html,你不可不知的有道云笔记Markdown指南【进阶版】
  14. C#中的特性,什么是特性.
  15. ffmpeg libx264 h264_nvenc 编码参数解析
  16. 投资理财--熊市笨小孩式交易75-25
  17. 使用jdbc创建一张员工表 员工表字段:编号,姓名,性别,年龄,职位,邮箱,电话
  18. 给新浪博客修改博客名字 超级简单图文教程
  19. 强化学习——环境库OpenAI Gym
  20. Delphi XE7 发布了

热门文章

  1. 直播丨Oracle 12cR2 ADG LGWR Library Cache案例分享
  2. AWR 报告深度解读:Time Model Statistics 信息的计算和获取
  3. AWR 报告深度解读:Redo Nowait指标的算法和诊断
  4. 解析云原生2.0架构设计的8大关键趋势
  5. 知道ThreadLocal吗?一起聊聊到底有啥用
  6. Python进阶丨如何创建你的第一个Python元类?
  7. 你掉进过“伪敏捷”的陷阱吗?
  8. mysql 1317,MySQL 中的-Error_code:1317-爱可生
  9. ip变更 mysql无法启动_ubuntu mysql 更改IP导致mysql无法启动
  10. SpringBoot和RabbitMQ集成