java 并发编程学习笔记(四)之 安全发布对象(单例模式实现几种实现方式)
【摘要】 安全发布对象
错误发布对象:
发布对象:使一个对象能被当前范围之外的代码所使用 ...
安全发布对象
错误发布对象:
发布对象:使一个对象能被当前范围之外的代码所使用
对象溢出:一种错误的发布,当一个对象还没有构造完成时,就使它被其他线程所见
如何 安全 发布对象呢 ?一般采用 以下四种方式
(1)首先来看一个 非安全发布对象代码:
-
@Slf4j
-
public class UnSafePublish {
-
-
private String[] states = {"a", "b", "c"};
-
-
/**
-
* 无法确保 其他的线程会通过调用此方法,来修改私有的成员变量
-
*
-
* @return
-
*/
-
public String[] getStates() {
-
return states;
-
-
}
-
-
public static void main(String[] args) {
-
UnSafePublish unSafePublish = new UnSafePublish();
-
log.info("{}", Arrays.toString(unSafePublish.getStates()));
-
-
unSafePublish.getStates()[0] = "d";
-
log.info("{}", Arrays.toString(unSafePublish.getStates()));
-
}
-
}
(2)非安全的 对象溢出
-
public class Escape {
-
-
private int thisCanBeEscape =0 ;
-
/**一种错误的发布,当一个对象还没有构造完成时,就使它被其他线程所见*/
-
public Escape() {
-
new InnerClass();
-
}
-
-
private class InnerClass{
-
public InnerClass(){
-
log.warn("{}",Escape.this.thisCanBeEscape);
-
}
-
}
-
public static void main(String[] args){
-
new Escape();
-
}
-
}
(3)单例模式的 几种方式比较
- 懒汉模式
-
/**
-
* 懒汉模式
-
* 单例的实例在第一次使用的时候进行创建
-
* <p>
-
* 在单线程的环境下,没有问题,但是在多线程的环境下就会出问题。
-
*/
-
@NotThreadSafe
-
@Slf4j
-
public class SingletonExample1 {
-
-
//私有构造函数
-
private SingletonExample1() {
-
-
}
-
-
//单例对象
-
private static SingletonExample1 instance = null;
-
-
-
//静态的工厂方法
-
//懒汉模式本身时线程不安全的,加上了synchronized关键字之后就可以实现安全
-
//但是降低了性能,因此并不推荐这种写法
-
public static synchronized SingletonExample1 getInstance() {
-
if (instance == null) {
-
instance = new SingletonExample1();
-
}
-
return instance;
-
}
-
}
- 饿汉模式
-
/**
-
* 饿汉模式
-
*/
-
public class SingletonExample2 {
-
-
-
private SingletonExample2() {
-
-
}
-
-
private static SingletonExample2 singletonExample2 = new SingletonExample2();
-
-
public static SingletonExample2 getInstance() {
-
return singletonExample2;
-
}
-
}
- 懒汉模式+ 双重检测同步锁
-
/**
-
* 懒汉模式 -》》双重同步锁单例模式
-
*/
-
@NotThreadSafe
-
@Slf4j
-
public class SingletonExample3 {
-
//私有构造函数
-
private SingletonExample3() {
-
-
}
-
/**
-
* 1.分配对象的内存空间
-
* 2.初始化对象
-
* 3.设置instance 指向刚分配的内存
-
* 在单线程的情况下没有问题,但是在多线程的情况下
-
*
-
* jvm 和cpu 优化,发生指令重排
-
*
-
* 1.分配对象的内存空间
-
* 2.设置instance 指向刚分配的内存
-
* 3.初始化对象
-
*
-
* 因此我们需要限制SingletonExample3类的创建的时候的指令重排,添加volatile关键字
-
*/
-
-
-
//单例对象
-
//volatile 加上 双重检测机制,禁止指令重排
-
private volatile static SingletonExample3 instance = null;
-
-
-
//静态的工厂方法
-
public static SingletonExample3 getInstance() {
-
if (instance == null) { //双重检测机制
-
synchronized (SingletonExample3.class) { //同步锁
-
if (instance == null) {
-
instance = new SingletonExample3();
-
}
-
}
-
}
-
return instance;
-
}
-
}
- 饿汉模式 (静态块的方式)
-
/**
-
* static 静态块的饿汉模式
-
*/
-
public class SingletonExample6 {
-
private SingletonExample6(){}
-
-
private static SingletonExample6 instance =null;
-
-
static {
-
instance = new SingletonExample6();
-
}
-
-
private static SingletonExample6 getInstance(){
-
return instance;
-
}
-
-
public static void main(String[] args){
-
System.out.println(getInstance());
-
System.out.println(getInstance());
-
}
-
}
- 枚举模式(最推荐)
-
/**
-
* 枚举模式,最安全
-
* 利用枚举的特性,一个枚举的构造方法只会被调用一次实现单例模式,推荐使用这种方式
-
* <p>
-
* 优点:1、相比懒汉模式,更能保证线程安全性
-
* 2、相比饿汉模式,也只会在第一次使用的时候进行创建实例,不会造成资源浪费
-
*/
-
@ThreadSafe
-
@Recommend
-
public class SingletonExample7 {
-
-
-
private SingletonExample7() {
-
}
-
-
public static SingletonExample7 getInstance() {
-
return Singleton.INSTANCE.getInstance();
-
}
-
-
private enum Singleton {
-
INSTANCE; //只有一个枚举变量,保证构造方法只调用一次
-
-
-
private SingletonExample7 singletonExample7;
-
-
//jvm保证这个方法绝对只调用一次
-
Singleton() {
-
System.out.println("我只会被调用一次");
-
singletonExample7 = new SingletonExample7();
-
}
-
-
public SingletonExample7 getInstance() {
-
return singletonExample7;
-
}
-
}
-
-
public static void main(String[] args) {
-
System.out.println(SingletonExample7.getInstance());
-
System.out.println(SingletonExample7.getInstance());
-
System.out.println(SingletonExample7.getInstance());
-
}
-
}
文章来源: blog.csdn.net,作者:血煞风雨城2018,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_31905135/article/details/84227362
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)