java单例模式的实现方法_java单例模式的4种实现方法

本文详细介绍了Java中实现单例模式的四种方法:饿汉模式、懒汉模式、双重检查锁定(DCL)模式、静态内部类及枚举类型。每种方式在多线程环境下的表现和线程安全性都进行了分析,帮助开发者更好地理解和运用单例模式。
摘要由CSDN通过智能技术生成

java单例模式的4种实现方法

发布时间:2020-05-29 16:32:12

来源:亿速云

阅读:128

作者:鸽子

单例模式的定义:单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例

单例模式的分类:立即加载/“饿汉模式”立即加载就是在使用类的时候已经将对象创建完毕

立即加载在中文语义上有“着急”,“急迫”的含义,因此又称为“饿汉模式”

普通的立即加载:public class MyObject{

private static MyObject mb = new MyObject();

private MyObject(){}

public static MyObject getInstance() {

return mb;

}

}

延迟加载/“懒汉模式”延迟加载是在调用getInstance()方法获取实例对象时才创建对象

延迟加载在中文语义上有“缓慢”,“不急迫”的含义,因此又称为“懒汉模式”

普通的延迟加载:public class MyObject{

private static MyObject mb;

private MyObject(){}

public static MyObject getInstance() {

if (mb == null)

mb = new MyObject();

return mb;

}

}

延迟加载/“懒汉模式”的缺点虽然上述的代码可以实现单例设计模式,但是在多线程环境中,前面的延迟加载的代码是完全错误的,根本不能实现保持单例的状态。因为多线程环境中,会存在多个线程调用getInstance()方法的情况,由于线程安全的问题就会导致创建出多个实例

单例模式的几种实现方法

1.使用DCL双重检查锁机制实现虽然直接在方法上使用synchronized上锁也能实现线程安全的单例,但是性能非常差,使用DCL机制后不仅线程安全还能使性能有所提升

属于延迟加载

代码:public class MyObject{

private static MyObject mb;

private MyObject(){}

public static MyObject getInstance() {

if (mb == null) {

synchronized (MyObject.class) {

if (mb == null) {

mb = new MyObject();

}

}

}

return mb;

}

}

2.使用静态内置类实现单例模式

静态内部类和静态属性属性会在类加载是时候执行,因此使用类的使用就将实例对象创建好了,属于立即加载

也因为只在类加载的时候加载一次并将对象创建完毕,因此线程是安全的

代码:public class MyObject{

//内部类方式

private static class MyObjectHandler {

private static MyObject mb =  new MyObject();

}

private MyObject(){}

public static MyObject getInstance() {

return MyObjectHandler.mb;

}

}

3.使用static代码块实现单例模式

和使用静态内部类的方式一样,也是在类加载的时候将实例对象创建好了,所以线程也是安全的

代码:public class MyObject{

private static MyObject mb = null;

private MyObject(){}

static {

mb = new MyObject();

}

public static MyObject getInstance() {

return mb;

}

}

4.使用enum枚举数据类型实现单例模式

在使用枚举类的时候构造方法会被自动调用,而且通过反射也无法获取枚举中的属性和方法因此线程也是安全的

代码:public enum MyEnum{

connectionFactory;

private Connection connection;

//枚举类的构造方法默认是private的,所以访问限定符private可以省略不写

MyEnum {

MysqlDataSource dataSource = new MysqlDataSource();

dataSource.setURL();

dataSource.setUser();

dataSource.setPassword();

connection = dataSource.getConnection();

}

public Connection getInstance() {

return connection;

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值