单例模式
单例模式的主要目的就是系统中有同一个类需要被反复使用,避免每次使用都重新创建和使用完之后就销毁,就只创建一次,每次使用都是用的同一个对象。
单例模式的实现在java中也是多种多样。
以下demo是常见的单例模式的简单实现以及效率对比,比较推荐使用静态内部类。
demo
package creationalpattern.singletonpattern;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @author tx
* @version 1.0
* @date 2024/1/6 10:55
* @description:
* 单例模式
* 只有一个实例,
* 主要用途是避免一个全局经常使用的类反复创建和销毁
* 可以通过如下方式保障只有一个实例:
*
*/
public class SingletonPattern {
public static void main(String[] args) {
/**
* 效率对比
*/
a();
b();
c();
d();
e();
}
public static void a(){
Long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SingletonA singletonAInstance = SingletonA.getSingletonAInstance();
singletonAInstance.run();
}
Long end = System.currentTimeMillis();
System.out.println("饿汉式");
System.out.println("耗时:ms:"+(end-start));
}
public static void b(){
Long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SingletonB singletonBInstance = SingletonB.getSingletonBInstance();
singletonBInstance.run();
}
Long end = System.currentTimeMillis();
System.out.println("懒汉式");
System.out.println("耗时:ms:"+(end-start));
}
public static void c(){
Long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SingletonC instance = SingletonC.getInstance();
instance.run();
}
Long end = System.currentTimeMillis();
System.out.println("优化懒汉式,双重校验");
System.out.println("耗时:ms:"+(end-start));
}
public static void d(){
Long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SingletonD instance = SingletonD.getInstance();
instance.run();
}
Long end = System.currentTimeMillis();
System.out.println("静态内部类");
System.out.println("耗时:ms:"+(end-start));
}
public static void e(){
Long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SingletonE instance = SingletonE.INSTANCE;
instance.run();
}
Long end = System.currentTimeMillis();
System.out.println("枚举");
System.out.println("耗时:ms:"+(end-start));
}
}
/**
* 饿汉式
* 类被加载的时候就创建了实例
*/
class SingletonA{
private static final SingletonA singletonAInstance = new SingletonA();
// 私有构造函数,不可被创建。
private SingletonA(){};
public static SingletonA getSingletonAInstance(){
return singletonAInstance;
}
public void run(){
// System.out.println(this);
}
}
/**
* 懒汉式
* 类的实例化被延迟到第一次使用该类。
* 用锁来保障线程安全,但是加锁有性能消耗
*/
class SingletonB{
private static final SingletonB singletonBInstance = null;
// 私有构造函数,不可被创建。
private SingletonB(){};
public static synchronized SingletonB getSingletonBInstance(){
if(singletonBInstance==null){
return new SingletonB();
}
return singletonBInstance;
}
public void run(){
// System.out.println(this);
}
}
/**
* 优化懒汉式
* 将锁加在方法内部的具体对象上,在锁内部在校验一次。
*/
class SingletonC{
private static SingletonC instance=null;
private SingletonC(){}
public static SingletonC getInstance(){
if(instance==null){
synchronized(SingletonC.class){
if (instance==null){
instance = new SingletonC();
}
}
}
return instance;
}
public void run(){
// System.out.println(this);
}
}
/**
* 加载延迟到类的延迟到第一次使用,实现相较于升级版懒汉式实现简单
*/
class SingletonD{
private static class Instance{
private static final SingletonD instance = new SingletonD();
}
public static SingletonD getInstance(){
return Instance.instance;
}
public void run(){
// System.out.println(this);
}
}
/**
* 枚举
*/
enum SingletonE{
INSTANCE,
;
public void run(){
// System.out.println(this);
}
}