设计模式:单例模式

15 篇文章 0 订阅
9 篇文章 0 订阅

–《菜鸟教程:单例模式》

单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建

普通单例模式

package cn.shentianlan.studytest.designmode.singleton;

/**
 * @author 渊蓝
 * @version 1.0
 * @description 普通单例模式,在类加载时即初始化完成
 * @date 2021/10/24 13:48
 */
public class GeneralSingleton {
    private static GeneralSingleton generalSingleton = new GeneralSingleton();
    private GeneralSingleton() {
    }
    public static GeneralSingleton getInstance(){
        return generalSingleton;
    }
}

懒汉式单例模式

package cn.shentianlan.studytest.designmode.singleton;

import java.util.concurrent.TimeUnit;

/**
 * @author 渊蓝
 * @version 1.0
 * @description 懒加载单例模式(多线程下会存在问题)
 * @date 2021/10/24 13:56
 */
public class LazySingleton {
    private static LazySingleton lazySingleton;
    private LazySingleton(){
    }
    public static LazySingleton getInstance(){
        if (lazySingleton==null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

多线程下懒汉式单例模式

package cn.shentianlan.studytest.designmode.singleton;

/**
 * @author 渊蓝
 * @version 1.0
 * @description 多线程下使用双重检查加锁方式实现单例模式
 * @date 2021/10/24 14:01
 */
public class LazyThreadSingleton {
    /**
     *  volatile 确保当lazyThreadSingleton被实例化之后,所有线程都能及时读取到该实例
     */
    private volatile static LazyThreadSingleton lazyThreadSingleton;
    private LazyThreadSingleton(){}
    public static LazyThreadSingleton getInstance(){
        if (lazyThreadSingleton == null){
            synchronized(LazyThreadSingleton.class){
                if (lazyThreadSingleton==null){
                    lazyThreadSingleton = new LazyThreadSingleton();
                }
            }
        }
        return lazyThreadSingleton;
    }

}

测试

为了能明显看到效果,在LazySingleton和LazyThreadSingleton创建实例时加上延时

package cn.shentianlan.studytest.designmode.singleton;

import java.util.concurrent.TimeUnit;

/**
 * @author 渊蓝
 * @version 1.0
 * @description 懒加载单例模式(多线程下会存在问题)
 * @date 2021/10/24 13:56
 */
public class LazySingleton {
    private static LazySingleton lazySingleton;
    private LazySingleton(){
    }
    public static LazySingleton getInstance() throws InterruptedException {
        if (lazySingleton==null){
            TimeUnit.MICROSECONDS.sleep(100);
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}
package cn.shentianlan.studytest.designmode.singleton;

import java.util.concurrent.TimeUnit;

/**
 * @author 渊蓝
 * @version 1.0
 * @description 多线程下使用双重检查加锁方式实现单例模式
 * @date 2021/10/24 14:01
 */
public class LazyThreadSingleton {
    /**
     *  volatile 确保当lazyThreadSingleton被实例化之后,所有线程都能及时读取到该实例
     */
    private volatile static LazyThreadSingleton lazyThreadSingleton;
    private LazyThreadSingleton(){}
    public static LazyThreadSingleton getInstance() throws InterruptedException {
        if (lazyThreadSingleton == null){
            TimeUnit.MICROSECONDS.sleep(100);
            synchronized(LazyThreadSingleton.class){
                if (lazyThreadSingleton==null){
                    lazyThreadSingleton = new LazyThreadSingleton();
                }
            }
        }
        return lazyThreadSingleton;
    }

}

单元测试类

package cn.shentianlan.studytest.designmode.singleton;

import org.junit.Test;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

/**
 * @author 渊蓝
 * @version 1.0
 * @description 单例模式测试类
 * @date 2021/10/24 14:13
 */
public class SingletonTest {
    @Test
    public void generalSingletonTest() {
        System.out.println("------------------generalSingletonTest----------------------------------");
        GeneralSingleton generalSingleton1 = GeneralSingleton.getInstance();
        GeneralSingleton generalSingleton2 = GeneralSingleton.getInstance();
        System.out.println("generalSingleton1:" + generalSingleton1 + "--" + generalSingleton1.hashCode());
        System.out.println("generalSingleton2:" + generalSingleton2 + "--" + generalSingleton2.hashCode());
        System.out.println("generalSingleton1==generalSingleton2:" + (generalSingleton1 == generalSingleton2));
        System.out.println();
    }

    /**
     * 单线程懒加载测试
     */
    @Test
    public void lazySingletonTest() throws InterruptedException {
        System.out.println("--------------------------lazySingletonTest:单线程懒加载测试------------------------------");
        LazySingleton lazySingleton1 = LazySingleton.getInstance();
        LazySingleton lazySingleton2 = LazySingleton.getInstance();
        System.out.println("lazySingleton1:" + lazySingleton1 + "--" + lazySingleton1.hashCode());
        System.out.println("lazySingleton2:" + lazySingleton2 + "--" + lazySingleton2.hashCode());
        System.out.println("lazySingleton1==lazySingleton2:" + (lazySingleton1 == lazySingleton2));
        System.out.println();
    }

    /**
     * 多线性懒加载测试
     * @throws InterruptedException
     */
    @Test
    public void multithreadedLazySingletonTest() throws InterruptedException {
        System.out.println("--------------------------multithreadedLazySingletonTest:多线程懒加载测试------------------------------");
        //线程数量
        final int THREAD_NUMBER = 3;
        CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUMBER);
        //多线程下测试
        for (int i = 0; i < THREAD_NUMBER; i++) {
            new Thread(() -> {
                LazySingleton lazySingleton = null;
                try {
                    lazySingleton = LazySingleton.getInstance();
                    System.out.println(lazySingleton);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
               countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        System.out.println();
    }

    @Test
    public void lazyThreadSingletonTest() throws InterruptedException {
        System.out.println("-----------------------lazyThreadSingletonTest---------------------------------------");
        LazyThreadSingleton lazyThreadSingleton1 = LazyThreadSingleton.getInstance();
        LazyThreadSingleton lazyThreadSingleton2 = LazyThreadSingleton.getInstance();
        System.out.println("lazyThreadSingleton1:" + lazyThreadSingleton1 + "--" + lazyThreadSingleton1.hashCode());
        System.out.println("lazyThreadSingleton2:" + lazyThreadSingleton2 + "--" + lazyThreadSingleton2.hashCode());
        System.out.println("lazyThreadSingleton1==lazyThreadSingleton2:" + (lazyThreadSingleton1 == lazyThreadSingleton2));
        System.out.println();
    }

    @Test
    public void multithreadedLazyThreadSingletonTest() throws InterruptedException {
        System.out.println("-----------------------multithreadedLazyThreadSingletonTest---------------------------------------");
        //线程数量
        final int THREAD_NUMBER = 3;
        CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUMBER);
        //多线程下测试
        for (int i = 0; i < THREAD_NUMBER; i++) {
            new Thread(() -> {
                LazyThreadSingleton lazySingleton = null;
                try {
                    lazySingleton = LazyThreadSingleton.getInstance();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(lazySingleton);
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        System.out.println();
    }


}

执行结果:

--------------------------multithreadedLazySingletonTest:多线程懒加载测试------------------------------
cn.shentianlan.studytest.designmode.singleton.LazySingleton@19ca2465
cn.shentianlan.studytest.designmode.singleton.LazySingleton@61540d60
cn.shentianlan.studytest.designmode.singleton.LazySingleton@15864d5a

--------------------------lazySingletonTest:单线程懒加载测试------------------------------
lazySingleton1:cn.shentianlan.studytest.designmode.singleton.LazySingleton@15864d5a--361123162
lazySingleton2:cn.shentianlan.studytest.designmode.singleton.LazySingleton@15864d5a--361123162
lazySingleton1==lazySingleton2:true

-----------------------lazyThreadSingletonTest---------------------------------------
lazyThreadSingleton1:cn.shentianlan.studytest.designmode.singleton.LazyThreadSingleton@3c679bde--1013423070
lazyThreadSingleton2:cn.shentianlan.studytest.designmode.singleton.LazyThreadSingleton@3c679bde--1013423070
lazyThreadSingleton1==lazyThreadSingleton2:true

-----------------------multithreadedLazyThreadSingletonTest---------------------------------------
cn.shentianlan.studytest.designmode.singleton.LazyThreadSingleton@3c679bde
cn.shentianlan.studytest.designmode.singleton.LazyThreadSingleton@3c679bde
cn.shentianlan.studytest.designmode.singleton.LazyThreadSingleton@3c679bde

------------------generalSingletonTest----------------------------------
generalSingleton1:cn.shentianlan.studytest.designmode.singleton.GeneralSingleton@2a098129--705265961
generalSingleton2:cn.shentianlan.studytest.designmode.singleton.GeneralSingleton@2a098129--705265961
generalSingleton1==generalSingleton2:true


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值