单例:只能实例化一个对象,使用场景比如打印机。

最推荐的是采用饿汉式;双重校验锁用到了大量的语法,不能保证这些语法在所用场合一定没问题,所以不是很推荐;总之简单的才是最好的,就饿汉式!!!

C++ 创建变量可以通过 类名 对象名,但是 JAVA 不行

C++ new 出来的对象需要手动回收,但是 JAVA 可以自动回收

C++ new 出来的对象需要用指针接收,但是 JAVA 对象变量就可以接收,或者说 JAVA 的对象变量就是指针

1、(懒汉,线程安全 ------ 不推荐)

public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

说明:在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的

2、(饿汉 ------ 推荐)

public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}

说明:instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载。所以,会出现在使用对象前就创建好,占用了资源

3、(静态内部类 ------ 推荐)

public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}

说明:第三种和第二种的区别在于,第三种类被装载也不会实例化对象,一定要调用 getInstance() 才会实例化,而且只实例化一次。

4、(双重校验锁 ------ 一般推荐<理解麻烦>)

public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton (){}
public static Singleton getSingleton() {
if (uniqueInstance == null) { // #1
synchronized (Singleton.class) { // #2
if (uniqueInstance == null) { // #3
uniqueInstance = new Singleton(); // #4
}
}
}
return singleton;
}
}

说明:和第一种方式比,这种方式只会第一次调用创建对象时使用同步锁

对象singleton 用 volatile 修饰,原因举例如下:

1. thread2进入#1, 假设这时子线程的uniqueInstance为空(java内存模型会从主线程拷贝一份uniqueInstance=null到子线程thread2),然后thread2让出CPU资源给thread3
2. thread3进入#1, 这时子线程的uniqueInstance还是为空(java内存模型会从主线程拷贝一份uniqueInstance=null到子线程thread3),然后thread3让出CPU资源给thread2
3. thread2会依次执行#2,#3,#4,最终在thread2里面实例化了uniqueInstance(由于是volatile修饰的变量,会马上同步到主线程的变量去),thread2执行完毕让出CPU资源给thread3
4. thread3接着#1跑下去,跑到#3的时候,会又一次从主线程拷贝一份uniqueInstance!=null回来,所以thread3就不会实例化对象

  上面解释的是 volatile 保证变量可见性的体现,使每个线程得到的变量来源都是唯一的;同时 volatile 还能保证变量的有序性," new Singleton "的执行其实是分三步走,第一:分配内存,第二:执行构造函数,第三:赋值,准确的说应该是引用;如果没有 volatile 修饰,在保证结果的情况下(单线程,或者是本线程中)编译器可能会打乱执行顺序,如果有另外一个线程在执行 #1 判断变量不为nll,但是此变量没有执行构造函数,获取的对象是不完整的,程序就可能发生错误。java的volatile顺序性方面比C++强,能保证此顺序执行。

  volatile 防止编译器把两个 if 优化成一个 if 。

疑问:

1、如果赋值不是原子操作,会不会出现,没完全赋值完成就被另外一个线程使用了

单例 ------ JAVA实现的更多相关文章

  1. 单例 (JAVA)

    java中单例模式是一种常见的设计模式,以下是它的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例 第一种(懒汉,线程不安全):  1 publ ...

  2. javaWeb项目中到底什么是单例,多例

    你用杯子喝可乐,喝完了不刷,继续去倒果汁喝,就是单例.你用杯子喝可乐,直接扔了杯子,换个杯子去倒果汁喝,就是多例. 数据库连接池就是单例模式,有且仅有一个连接池管理者,管理多个连接池对象. 1. 什么 ...

  3. java 单例

    Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉式单例. 饿汉式和懒汉式区别 从名字上来说,饿汉和懒汉, 饿汉就是类一旦加载,就把单例初始化完成,保证 ...

  4. Java设计模式之单例

    一.Java中的单例: 特点: ① 单例类只有一个实例 ② 单例类必须自己创建自己唯一实例 ③ 单例类必须给所有其他对象提供这一实例 二.两种模式: ①懒汉式单例<线程不安全> 在类加载时 ...

  5. java单例的几种实现方法

    java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...

  6. Java 多线程之单例设计模式

    转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...

  7. java单例类/

    java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...

  8. java单例-积木系列

    一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档.   懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒 ...

  9. 如何防止JAVA反射对单例类的攻击?

    在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...

随机推荐

  1. 从零开始的Python学习Episode 3——字符串格式化与for循环

    一.字符串格式化 利用一段注释记录想要输出的字符串格式,并用 %s . %d 或 %f 依次代替要输出的数据(%s代表字符串,%d代表数字,%f代表浮点数),然后在这段注释之后依次加上要输出的数据. ...

  2. Learning Spatial-Temporal Regularized Correlation Filters for Visual Tracking---随笔

    Learning Spatial-Temporal Regularized Correlation Filters for Visual Tracking DCF跟踪算法因边界效应,鲁棒性较差.SRD ...

  3. Python3 Tkinter-Scale

    1.创建 from tkinter import * root=Tk() Scale(root).pack() root.mainloop() 2.参数 from tkinter import * r ...

  4. 一:HDFS 用户指导

    1.hdfs的牛逼特性 Hadoop, including HDFS, is well suited for distributed storage and distributed processin ...

  5. Notes of the scrum meeting(12.10)

    meeting time:20:00~20:30p.m.,December 10th,2013 meeting place:20号公寓前 attendees: 顾育豪                  ...

  6. 什么是BCL

    原文: 原文:https://www.cnblogs.com/1996V/p/9037603.html 什么是BCL 当你通过VS创建一个项目后,你这个项目就已经引用好了通过.NET下的语言编写好的一 ...

  7. iOS-根据两个经纬度计算相距距离

    CLLocation *orig=[[[CLLocation alloc] initWithLatitude:[mainDelegate.latitude_self doubleValue] long ...

  8. ARKit----学习一

    一.ARKit的简介 开始进入正题吧 ARKit在iOS 11上推出的一个AR移动平台,支持A9以上的处理器,不支持模拟器.ARKit使用相机捕捉现实世界,使用SceneKit,SpriteKit或者 ...

  9. FineCMS介绍

      产品简介 FineCMS(简称免费版.企业版.公益版)是一款基于PHP+MySql+CI框架开发的高效简洁的中小型内容管理系统,面向多终端包括Pc端网页和移动端网页,支持自定义内容模型和会员模型, ...

  10. 【Python】python更新数据库脚本两种方法

    最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新. 第一种:使用python的MySQLdb模块利用原生的sql语句进行更新   1 import ...