设计模式 最基础也最重要的单例模式
作者:互联网
饿汉式单例
顾名思义 很饿很着急 会在程序运行一开始就吧类对象加载出来
所以有着可能浪费资源的缺点
简单例子:
//饿汉式单例
public class Hungry {
//可能会导致空间的浪费
private byte[] data=new byte[1024*1024];
//核心思想 构造器私有化
private Hungry(){
}
private final static Hungry HUNGRY=new Hungry();
public static Hungry getInstance(){
return HUNGRY;
}
}
懒汉式单例
懒汉式单例的思想是 当需要用到我时才创建对象 但是简单的写法会在多线程出现问题
//懒汉式单例
public class LazyMan {
private LazyMan(){
System.out.println(Thread.currentThread().getName()+"执行了创建方法");
}
private static LazyMan lazyMan;
public static LazyMan getInstance(){
if(lazyMan == null) {
lazyMan = new LazyMan();
}
return lazyMan;
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{LazyMan.getInstance();}).start();
}
}
}
运行结果可能会随机出现多个线程创建了对象 不符合单例模式的思想
双重锁实现多线程懒汉实现
//懒汉式单例
public class LazyMan {
private LazyMan(){
System.out.println(Thread.currentThread().getName()+"执行了创建方法");
}
private static LazyMan lazyMan;
public static LazyMan getInstance(){
//外层判断主要是优化 使得不是每次都要获取锁
//双重锁懒汉式 称为DCL懒汉
if(lazyMan==null){
synchronized (LazyMan.class){
if(lazyMan == null) {
lazyMan = new LazyMan();
}
}
}
return lazyMan;
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{LazyMan.getInstance();}).start();
}
}
}
通过锁就可以实现只能一个线程获取对象
但是实际上这样在极端情况下也不是安全的 原因在与语句
lazyMan = new LazyMan();
底层是执行了很多步骤的 同时并不是原子操作
有可能出现第一个线程在创建对象 还没完全创建完毕时 第二个线程判断已经创建完毕 最后返回空对象
解决方法:
添加volatile
关键字
private volatile static LazyMan lazyMan;
标签:模式,LazyMan,public,static,private,单例,设计模式,lazyMan 来源: https://www.cnblogs.com/OfflineBoy/p/15244878.html