java 单例 字典 动态_Java单例模式

Java单例模式

什么是单例模式

单例模式是在程序中,一个类保证只有一个实例,并提供统一的访问入口。

为什么要用单例模式

节省内存 节省计算如对象实例中的一样的,那就不用每次都创建一个对象

方便管理 因为单例提供一个统一的访问入口,不需要创建N多个对象,很多工具类都用了单例实现,如日志、字符串工具类

保证结果正确 比如统计网站的访问次数等等

单例的实现方式

饿汉式 程序启动的时候就会实例化

1 public class Singleton {

2

3 private static Singleton singleton = new Singleton();

4

5 private Singleton(){}

6

7 public static Singleton getInstance(){

8 return singleton;

9 }

10 }

饿汉静态代码块形势

1 public class Singleton {

2

3 private static Singleton singleton;

4 static {

5 singleton = new Singleton();

6 }

7 private Singleton(){}

8

9 public static Singleton getInstance(){

10 return singleton;

11 }

12 }

懒汉式 非线程安全的实现

1 public class Singleton {

2

3 private static Singleton singleton;

4 private Singleton(){}

5

6 public static Singleton getInstance(){

7 if (singleton == null){

8 return singleton = new Singleton();

9 }

10 return singleton;

11 }

12 }

线程安全的实现,单性能低

1 public class Singleton {

2

3 private static Singleton singleton;

4 private Singleton(){}

5

6 public static synchronized Singleton getInstance(){

7 if (singleton == null){

8 return singleton = new Singleton();

9 }

10 return singleton;

11 }

12 }

线程安全的实现,双重校验

注意:两个校验都必须加,如果第二个没有加校验,当两个线程都通过了第一个if校验,此时会有一个线程进入同步代码块,创建singleton实例,接着第二个线程也会进入同步代码块,并会在创建一个singleton。那么这样就破坏了单例。如果不加第一个if校验,那么所有的程序就会串行执行,影响执行效率。所以两个校验都必须存在

1 public class Singleton {

2 /**由于 return singleton = new Singleton(); 这行代码在JVM中会分为三步处理

3 * 1.给singleton分配内存空间

4 * 2.调用singleton的构造函数开初始化

5 * 3.将singleton对象指向分配的内存空间(这步执行了就singleton就不是null了)

6 *

7 * 由于CPU会对这三个步骤重排序,如果顺序是1 3 2,那么就可能出现singleton就不是空的,但并没有初始化singleton

8 * 这样第二个线程可能拿到的就是为初始化的singleton,所以使用volatile来修饰singleton,防止重排序的问题

9 */

10 private static volatile Singleton singleton;

11 private Singleton(){}

12

13 public static Singleton getInstance(){

14 if (singleton == null){

15 synchronized (Singleton.class) {

16 if (singleton == null) {

17 return singleton = new Singleton();

18 }

19 }

20 }

21 return singleton;

22 }

23 }

懒汉之静态内部类的方式

这种方式能保证线程的安全线性,当Singleton被装载时,并不会立刻实例化静态内部类SingletonInstance,而是在需要时才会实例化

1 public class Singleton {

2

3 private static class SingletonInstance{

4 private static final Singleton singleton = new Singleton();

5 }

6 private Singleton(){}

7

8 public static Singleton getInstance(){

9 return SingletonInstance.singleton;

10 }

11 }

枚举实现单例 实现简单、线程安全、可以防止反序列化、反射的方式破坏单例模式,如果通过反序列化或反射的方式创建实例,会抛出异常。这种方式是最好的实现的方式

1 public enum Singleton{

2 INSTANCE;

3 public void whateverMethod(){

4 }

5 }

原文链接:https://www.cnblogs.com/aaronzheng/p/12111931.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值