JAVA的单例模式实例分析
JAVA的单例模式实例分析
这篇文章主要介绍“JAVA的单例模式实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JAVA的单例模式实例分析”文章能帮助大家解决问题。
一、单例模式是什么?
单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
作用:单例模式是保证系统实例唯一性的重要手段。用于一个全局类对象在多个地方被使用的场景下,保障了整个系统只有一个对象被使用,很好的节约了资源
实现方法:将类的实例化方法私有化来防止程序通过其他方式创建该类的实例,提供一个全局唯一获取该类实例的方法帮助用户获取类的实例。
实现单例模式很简单,每次获取前先判断系统是否已经存在单例对象,没有就创建,有就返回这个对象。单例模式常见的写法有懒汉式单例和饿汉式单例。
二、懒汉式单例
定义:类加载时没有生成单例,第一次调用 getlnstance 方法时创建这个单例。
publicclassLazySingleton{//定义一个私有的静态对象instance,静态方法和属性属于类,能保障单例对象的唯一性privatestaticLazySingletoninstance;//私有化构造方法,只能在本类中被访问,其他类中不能通过构造方法直接创建对象privateLazySingleton(){}//提供一个全局唯一获取实例的方法publicstaticsynchronizedLazySingletongetInstance(){if(instance==null){instance=newLazySingleton();}returninstance;}}
懒汉模式在获取对象实例时做了加锁操作,因此是线程安全的
测试代码与结果
publicclassTestLazySingleton{publicstaticvoidmain(String[]args){LazySingletonlazySingleton1=LazySingleton.getInstance();LazySingletonlazySingleton2=LazySingleton.getInstance();LazySingletonlazySingleton3=LazySingleton.getInstance();System.out.println(lazySingleton1);System.out.println(lazySingleton2);System.out.println(lazySingleton3);}}
从上图中可以看出虽然获取了三次实例,但每次获取的都是同一个实例,即一个类只有一个实例。
三、饿汉式单例
定义:该模式的特点是类一旦加载就创建一个单例,在调用 getInstance 方法之前单例已经存在。
publicclassHungrySingleton{//类加载完成后该类的实例便已经存在privatestaticHungrySingletoninstance=newHungrySingleton();//私有化构造方法privateHungrySingleton(){}//类加载后实例就存在,不会出现线程安全问题,不需要加锁publicstaticHungrySingletongetInstance(){returninstance;}}
测试代码和结果
publicclassTestHungrySingleton{publicstaticvoidmain(String[]args){HungrySingletonhungrySingleton1=HungrySingleton.getInstance();HungrySingletonhungrySingleton2=HungrySingleton.getInstance();HungrySingletonhungrySingleton3=HungrySingleton.getInstance();System.out.println(hungrySingleton1);System.out.println(hungrySingleton2);System.out.println(hungrySingleton3);}}
从上图看出饿汉式单例在整个运行过程中也只存在一个实例。
懒汉式单例和饿汉式单例的区别
1.懒汉模式在类中定义了单例但是并未实例化,实例化是在方法中实现的,而饿汉模式定义的时候就进行了实例化
2.懒汉模式需要在获取实例的方法上加锁保证线程安全,饿汉模式不需要加锁。
四、双重校验锁
懒汉模式用到了synchronized,会导致很大的性能开销,并且加锁其实只需要在第一次初始化的时候用到,之后的调用都没必要再进行加锁。
双重校验锁在懒汉模式的基础上做了进一步的优化,给静态对象加上volatile来保证有序性,第一次获取对象时通过synchronize(Singleton.class)保障操作的唯一性。
publicclassLockSingleton{privatevolatilestaticLockSingletonlockSingleton;privateLockSingleton(){}publicstaticLockSingletongetInstance(){if(lockSingleton==null){synchronized(LockSingleton.class){if(lockSingleton==null){lockSingleton=newLockSingleton();}}}returnlockSingleton;}}
测试代码与结果
publicclassLockTest{publicstaticvoidmain(String[]args){LockSingletonlockSingleton1=LockSingleton.getInstance();LockSingletonlockSingleton2=LockSingleton.getInstance();LockSingletonlockSingleton3=LockSingleton.getInstance();System.out.println(lockSingleton1);System.out.println(lockSingleton2);System.out.println(lockSingleton3);}}
执行双重检查是因为,如果多个线程同时了通过了第一次检查,并且其中一个线程首先通过了第二次检查并实例化了对象,那么剩余通过了第一次检查的线程就不会再去实例化对象。
除了第一次创建实例的时候会出现加锁的情况,后续的所有调用都会避免加锁而直接返回,解决了性能消耗的问题。
关于“JAVA的单例模式实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注恰卡编程网行业资讯频道,小编每天都会为大家更新不同的知识点。
推荐阅读
-
java fileinputstream中文乱码如何解决
javafileinputstream中文乱码如何解决今天小编给...
-
java实现点赞功能
-
java实现简单点赞功能
-
java实现收藏功能
-
java输入空行结束问题怎么解决
-
Java线程中常用的操作有哪些
-
java输入时怎么通过回车来结束输入
java输入时怎么通过回车来结束输入这篇文章主要介绍“java输入...
-
Java数据结构之线索化二叉树怎么实现
Java数据结构之线索化二叉树怎么实现这篇文章主要介绍“Java数...
-
Java中的泛型怎么理解
Java中的泛型怎么理解本篇内容介绍了“Java中的泛型怎么理解”...
-
Java字符串编码解码性能怎么提升
Java字符串编码解码性能怎么提升这篇“Java字符串编码解码性能...