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

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

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. 【转载】图解Java常用数据结构(一)

    图解Java常用数据结构(一)  作者:大道方圆 原文:https://www.cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识, 系统化看了下Jav ...

  2. HDU 3264/POJ 3831 Open-air shopping malls(计算几何+二分)(2009 Asia Ningbo Regional)

    Description The city of M is a famous shopping city and its open-air shopping malls are extremely at ...

  3. 硬件PCB Layout布局布线Checklist检查表(通用版)

    按部位分类 技术规范内容 1 PCB布线与布局 PCB布线与布局隔离准则:强弱电流隔离.大小电压隔离,高低频率隔离.输入输出隔离.数字模拟隔离.输入输出隔离,分界标准为相差一个数量级.隔离方法包括:空 ...

  4. Jamie and Alarm Snooze

    Description Jamie loves sleeping. One day, he decides that he needs to wake up at exactly hh: mm. Ho ...

  5. Easy Summation

    Description You are encountered with a traditional problem concerning the sums of powers. Given two ...

  6. 搭建github

    http://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html

  7. 《学习OpenCV》课后习题解答3

    题目:(P104) 创建一个大小为100*100的三通道RGB图像.将它的元素全部置0.使用指针算法以(20,5)与(40,20)为项点绘制一个绿色平面. 解答: #include "cv. ...

  8. requests保持cookies的问题

    获取cookie,返回CookieJar对象:url = 'http://www.baidu.com'r = requests.get(url) r.cookies#将CookieJar转为字典: c ...

  9. Android各分辨率定义的图片规格

    我们定义的app图片规格 app图标需要分iphone和android两套 iphone: 名称 Iphone4 Iphone5 手机尺寸 960*640(高*宽) 1136*640 (高*宽) 电池 ...

  10. [剑指Offer] 47.求1+2+3+...+n

    题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). [思路]用&&的短路思想来求和 ...