博客
关于我
单例模式
阅读量:224 次
发布时间:2019-03-01

本文共 3591 字,大约阅读时间需要 11 分钟。

文章目录

1 饿汉式

/** * @author :wyaoyao * @date : 2020-04-06 14:32 * 单例模式:饿汉式 * 线程安全 * 但是在不使用的时候占用内存,因为通过static是类主动加载,不能能够懒加载 */public class SingletonSimple1 {       private static final SingletonSimple1 instance = new SingletonSimple1();    // 构造私有化。不允许外部调用    private SingletonSimple1() {       }    public static SingletonSimple1 getInstance() {           return instance;    }}
  • 线程安全
  • 但是在不使用的时候占用内存,通过static是类主动加载,不能能够懒加载

测试

// 测试@Testpublic void test() {       SingletonSimple1 instance1 = SingletonSimple1.getInstance();    SingletonSimple1 instance2 = SingletonSimple1.getInstance();    Assert.assertTrue(instance1 == instance2);}

懒汉式

/** * @author :wyaoyao * @date : 2020-04-06 14:41 * 饿汉式:懒加载 */public class SingletonSimple2 {       private static SingletonSimple2 instance;    private SingletonSimple2(){       }    // 存在线程安全问题    public static SingletonSimple2 getInstance(){           if(null == instance){               instance = new SingletonSimple2();        }        return instance;    }}
  • 这个懒加载,在使用的时候才会创建对象,但是线程不安全

测试

// 测试,构建100线程去创建对象,测试是否线程安全@Testpublic void test2() {       for (int i = 0; i<100; i++){           new Thread(()->{               SingletonSimple2 instance = SingletonSimple2.getInstance();            System.out.println(instance);        },"T"+i).start();    }    /**     * 不安全,并不是单例的,SingletonSimple2@608f35ee,SingletonSimple2@5617e729     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@608f35ee     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@5617e729     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@7df5ed4e     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@7df5ed4e     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@7df5ed4e     */}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jSHdx6qg-1599738853607)(evernotecid://FA2713E9-40BE-49E5-BF9D-E3ACD77E4128/appyinxiangcom/21741088/ENResource/p542)]

解决懒汉式的线程不安全

方案一

// 加锁    public synchronized static SingletonSimple2 getInstance(){           if(null == instance){               instance = new SingletonSimple2();        }        return instance;    }

问题

  • 除了第一次是创建,以后都是读的操作,每次都会加锁,效率不高

方案二

double check

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D4qVca7W-1599738853614)(evernotecid://FA2713E9-40BE-49E5-BF9D-E3ACD77E4128/appyinxiangcom/21741088/ENResource/p543)]

也存在问题:可能会引起npe

解决这个问题很简单,使用volatile关键字即可

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

ClassHolder

  • 支持懒加载
  • 线程安全
  • 不会npe
public class SingletonSimple5 {       private SingletonSimple5(){       }    private static class InstanceHolder {           private final static SingletonSimple5 instance = new SingletonSimple5();    }    public static SingletonSimple5 getInstance(){           return InstanceHolder.instance;    }}

枚举方式

转载地址:http://obrv.baihongyu.com/

你可能感兴趣的文章
mysql 审核_审核MySQL数据库上的登录
查看>>
mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
查看>>
mysql 导入导出大文件
查看>>
MySQL 导出数据
查看>>
mysql 将null转代为0
查看>>
mysql 常用
查看>>
MySQL 常用列类型
查看>>
mysql 常用命令
查看>>
Mysql 常见ALTER TABLE操作
查看>>
MySQL 常见的 9 种优化方法
查看>>
MySQL 常见的开放性问题
查看>>
Mysql 常见错误
查看>>
mysql 常见问题
查看>>
MYSQL 幻读(Phantom Problem)不可重复读
查看>>
mysql 往字段后面加字符串
查看>>
mysql 快速自增假数据, 新增假数据,mysql自增假数据
查看>>
Mysql 批量修改四种方式效率对比(一)
查看>>
Mysql 报错 Field 'id' doesn't have a default value
查看>>
MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
查看>>
Mysql 拼接多个字段作为查询条件查询方法
查看>>