标签:构造方法 博文 自己 开始 tde 初始化 情况 new code
本篇博文,将整理关于单例模式(就是让一个类从始至终,只能产生一个对象,而且spring管理的类也全部是单例模式的)与多线程摩擦出的火花
public class demo01 {
//要实现单例,肯定不能new对象,因此我们私有化构造函数
private demo01(){}
//定义一个属于本类的单例对象,每次返回的都是这个对象
public static demo01 instance = null;
//因为我们没有自己创造出来的对象了,故提供一个静态工厂方法,返回对象的实例
public static demo01 getInstance(){
if (instance==null){ //在多线程并发访问的情况下,是存在线程安全问题的
instance = new demo01();
return instance;
}
return instance;
}
}
public class demo02 {
//要实现单例,肯定不能new对象,因此我们私有化构造函数
private demo02(){}
//定义一个属于本类的单例对象,每次返回的都是这个对象
private static demo02 instance = new demo02(); // 静态域
//因为我们没有自己创造出来的对象了,故提供一个静态工厂方法,返回对象的实例
public static demo02 getInstance(){
return instance;
}
}
1 . 如果在构造函数中有过多的其他耗时操作的话,对象的创建会很慢
2 . 而且对象创建出来了还不一定会马上使用,造成资源的浪费
public class demo05 {
//要实现单例,肯定不能new对象,因此我们私有化构造函数
private demo05(){}
//注意点, 下面两段代码是有先后顺序的,假如说颠倒顺序,那么已经初始化的实例也会被重置为null
public static demo05 instance = null;
static {
instance = new demo05();
}
//因为我们没有自己创造出来的对象了,故提供一个静态工厂方法,返回对象的实例
public static demo05 getInstance(){
return instance;
}
}
1 . 如果在构造函数中有过多的其他耗时操作的话,对象的创建会很慢
2 . 而且对象创建出来了还不一定会马上使用,造成资源的浪费
public class demo03 {
//要实现单例,肯定不能new对象,因此我们私有化构造函数
private demo03(){}
//定义一个属于本类的单例对象,每次返回的都是这个对象
public static demo03 instance = null;
public static synchronized demo03 getInstance(){
if (instance==null){
instance = new demo03();
return instance;
}
return instance;
}
}
public class demo04 {
//要实现单例,肯定不能new对象,因此我们私有化构造函数
private demo04(){}
//定义一个属于本类的单例对象,每次返回的都是这个对象
public static volatile demo04 volatile instance = null;
// 双重同步锁单例模式
public static demo04 getInstance(){
if (instance==null){ // 检测 1
synchronized (demo04.class){ //锁
if (instance==null){ //检查 2
instance = new demo04();
}
}
return instance;
}
return instance;
}
}
这就要从CPU的指令说起, 当我们执行
new demo04();
分下面三步走
在单线程的情况下是不会发生任何线程安全问题的,但是! 多线程就会受到 指令重排序的影响, JVM和CPU优化--指令重排序可能出现下面的顺序
这时候双重同步锁单例模式就会出现问题,比如AB两条线程 A运行到指令3却没有真正创建对象 , 然后B去判断instance此时不为空,拿到了instance,一旦调用就会出现问题
public class demo06 {
private demo06(){}
public static demo06 getInstance(){
return Singleton.INSTANCE.getDemo06Instance();
}
//私有的枚举类
private enum Singleton{
INSTANCE;
private demo06 demo06Instance;
//JVM保证此构造方法绝对只会调用一次
Singleton(){
demo06Instance= new demo06(); //调用外部类私有的构造方法
}
public demo06 getDemo06Instance(){
return demo06Instance;
}
}
}
推荐使用这种方法
标签:构造方法 博文 自己 开始 tde 初始化 情况 new code
原文地址:https://www.cnblogs.com/ZhuChangwu/p/11150356.html