java单例模式的4种实现方法
单例模式的定义:
- 单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
单例模式的分类:
- 立即加载/“饿汉模式”
- 立即加载就是在使用类的时候已经将对象创建完毕
- 立即加载在中文语义上有“着急”,“急迫”的含义,因此又称为“饿汉模式”
- 普通的立即加载:
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双重检查锁机制实现
10余年的呼图壁网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。网络营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整呼图壁建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联从事“呼图壁网站设计”,“呼图壁网站推广”以来,每个客户项目都认真落实执行。
- 虽然直接在方法上使用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;
}
}
文章标题:java单例模式的4种实现方法
本文路径:http://cdiso.cn/article/jhoeeh.html