什么是设计模式
设计模式是经常使用、大多数人知道,有特定目录的代码设计经验。设计模式可以提高代码可维护性,可提升代码运行效率,也能提高系统可靠性。设计模式可以分为三类,分别是创建型、结构型和行为型。以下就单例模式简要概述。
什么是单例模式
单例模式涉及到一个类,这个类创建自己的对象,任何时候有且只创建一个对象。单例模式也是属于创建型模式,是提供创建对象的最佳方式。
单例模式创建方式
单例对象的创建方式有饿汉模式、懒汉模式、双重校验锁、枚举等。
小试牛刀
下面分别用懒汉模式、饿汉模式、双重检验锁、枚举进行简要实战
1、懒汉模式
实例:
/**
* 懒汉模式
* @author senfel
* @version 1.0
* @date 2022/8/10 9:25
*/
public class LazySingleModel {
/**
* 私有化实例接收
*/
private static LazySingleModel instance;
/**
* 构造函数私有化
*/
private LazySingleModel(){};
/**
* 线程不安全
* @return
*/
public static LazySingleModel getInstanceByNotSec(){
if(Objects.isNull(instance)){
instance = new LazySingleModel();
}
return instance;
}
/**
* 线程安全
* synchronized 锁会增加性能开销
* @return
*/
public static synchronized LazySingleModel getInstanceBySec(){
if(Objects.isNull(instance)){
instance = new LazySingleModel();
}
return instance;
}
}
测试:
/**
* 测试单例模式
* @author senfel
* @version 1.0
* @date 2022/8/10 9:30
*/
@Slf4j
@SpringBootTest
public class TestSingleModel {
@SneakyThrows
@Test
public void testLazySingle(){
//同步
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i= 0;i<5;i++){
MyThread myThread = new MyThread(countDownLatch);
myThread.start();
countDownLatch.countDown();
}
}
class MyThread extends Thread{
private CountDownLatch countDownLatch;
MyThread(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
super.run();
try {
countDownLatch.await();
//线程不安全的测试对象pub.iit.testdemo.single.LazySingleModel@f8270d2
//线程不安全的测试对象pub.iit.testdemo.single.LazySingleModel@4be8a962
//线程不安全的测试对象pub.iit.testdemo.single.LazySingleModel@6f85a94
//线程不安全的测试对象pub.iit.testdemo.single.LazySingleModel@7ea84aaf
//线程不安全的测试对象pub.iit.testdemo.single.LazySingleModel@f8270d2
//log.error("线程不安全的测试对象{}",LazySingleModel.getInstanceByNotSec());
//线程安全的测试对象pub.iit.testdemo.single.LazySingleModel@347e8c13
//线程安全的测试对象pub.iit.testdemo.single.LazySingleModel@347e8c13
//线程安全的测试对象pub.iit.testdemo.single.LazySingleModel@347e8c13
//线程安全的测试对象pub.iit.testdemo.single.LazySingleModel@347e8c13
//线程安全的测试对象pub.iit.testdemo.single.LazySingleModel@347e8c13
log.error("线程安全的测试对象{}",LazySingleModel.getInstanceBySec());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2、饿汉模式
实例:
/**
*
* 饿汉模式
* @author senfel
* @version 1.0
* @date 2022/8/10 10:16
*/
public class HungrySigleModel {
/**
* 直接实例化
*/
private static HungrySigleModel instance = new HungrySigleModel();
/**
* 构造函数私有化
*/
private HungrySigleModel(){};
/**
* 线程安全
* @return
*/
public static HungrySigleModel getInstance(){
return instance;
}
}
测试:
/**
* 测试单例模式
* @author senfel
* @version 1.0
* @date 2022/8/10 9:30
*/
@Slf4j
@SpringBootTest
public class TestSingleModel {
@Test
public void testHungrySingle(){
//同步
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i= 0;i<5;i++){
MyThread myThread = new MyThread(countDownLatch);
myThread.start();
countDownLatch.countDown();
}
}
class MyThread extends Thread{
private CountDownLatch countDownLatch;
MyThread(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
super.run();
try {
countDownLatch.await();
//线程安全的测试对象:pub.iit.testdemo.single.HungrySigleModel@1da95e6d
//线程安全的测试对象:pub.iit.testdemo.single.HungrySigleModel@1da95e6d
//线程安全的测试对象:pub.iit.testdemo.single.HungrySigleModel@1da95e6d
//线程安全的测试对象:pub.iit.testdemo.single.HungrySigleModel@1da95e6d
//线程安全的测试对象:pub.iit.testdemo.single.HungrySigleModel@1da95e6d
System.err.println("线程安全的测试对象:"+HungrySigleModel.getInstance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3、双重校验锁
实例:
/**
* 双重校验锁
* @author senfel
* @version 1.0
* @date 2022/8/10 10:25
*/
public class DoubleLockSingleModel {
/**
* 实体可见
*/
private static volatile DoubleLockSingleModel instance;
/**
* 构造私有化
*/
private DoubleLockSingleModel(){};
/**
* 双重校验锁 线程安全
* @return
*/
public static DoubleLockSingleModel getInstance(){
if(Objects.isNull(instance)){
synchronized (DoubleLockSingleModel.class){
if(Objects.isNull(instance)){
instance = new DoubleLockSingleModel();
}
}
}
return instance;
}
}
测试:
/**
* 测试单例模式
* @author senfel
* @version 1.0
* @date 2022/8/10 9:30
*/
@Slf4j
@SpringBootTest
public class TestSingleModel {
@Test
public void testDoubleLock(){
//同步
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i= 0;i<5;i++){
MyThread myThread = new MyThread(countDownLatch);
myThread.start();
countDownLatch.countDown();
}
}
class MyThread extends Thread{
private CountDownLatch countDownLatch;
MyThread(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
super.run();
try {
countDownLatch.await();
//线程安全的测试对象:pub.iit.testdemo.single.DoubleLockSingleModel@50193d97
//线程安全的测试对象:pub.iit.testdemo.single.DoubleLockSingleModel@50193d97
//线程安全的测试对象:pub.iit.testdemo.single.DoubleLockSingleModel@50193d97
//线程安全的测试对象:pub.iit.testdemo.single.DoubleLockSingleModel@50193d97
//线程安全的测试对象:pub.iit.testdemo.single.DoubleLockSingleModel@50193d97
System.err.println("线程安全的测试对象:"+ DoubleLockSingleModel.getInstance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4、枚举类型,天然单例,因为枚举只会实例化一次
实例:
/**
* 枚举单例
* 天然线程安全,推荐使用
* @author senfel
* @version 1.0
* @date 2022/8/10 10:33
*/
public class EnumSingleModel {
/**
* 构造私有
*/
private EnumSingleModel(){}
enum EnumModel{
INSTANCE;
private EnumSingleModel enumSingleModel;
private EnumModel(){
enumSingleModel = new EnumSingleModel();
}
}
/**
* 获取对象
* @return
*/
public static EnumSingleModel getInstance(){
return EnumModel.INSTANCE.enumSingleModel;
}
}
测试:
/**
* 测试单例模式
* @author senfel
* @version 1.0
* @date 2022/8/10 9:30
*/
@Slf4j
@SpringBootTest
public class TestSingleModel {
@Test
public void testEnumSingle(){
//同步
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i= 0;i<5;i++){
MyThread myThread = new MyThread(countDownLatch);
myThread.start();
countDownLatch.countDown();
}
}
class MyThread extends Thread{
private CountDownLatch countDownLatch;
MyThread(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
super.run();
try {
countDownLatch.await();
//线程安全的测试对象:pub.iit.testdemo.single.EnumSingleModel@5f2d78c3
//线程安全的测试对象:pub.iit.testdemo.single.EnumSingleModel@5f2d78c3
//线程安全的测试对象:pub.iit.testdemo.single.EnumSingleModel@5f2d78c3
//线程安全的测试对象:pub.iit.testdemo.single.EnumSingleModel@5f2d78c3
//线程安全的测试对象:pub.iit.testdemo.single.EnumSingleModel@5f2d78c3
System.err.println("线程安全的测试对象:"+ EnumSingleModel.getInstance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154698.html