栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java23种设计模式之单例模式(Singleton)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java23种设计模式之单例模式(Singleton)

  • ​​​概念: 单例模式在23种设计模式中属于创建型模式,是常见的设计模式之一。
  • 案例:

    这里以经典的数据库驱动连接工具类为例;

    数据库连接工具类在各个业务的dao层会被初始化调用;

    而每一次初始化都会在堆内存中申请一片空间,这是对堆内存资源的浪费;

    如果在堆内存只开辟一片空间,各个业务的Dao层建立不同的引用进行操作,就可以资源利用最大化;                                                                                                                                                                                                                                                                                          单例设计模式就应运而生,它就是为了解决对象初始化,造成资源浪费的情况;

  • 术语                                                                                                                                          单例:Singleton 
  • 三要素:
    • 私有的构造方法;

    • 指向自己实例的私有静态引用;

    • 以自己实例为返回值的静态的公有方法。

  • 分类         

         1.饿汉式(静态常量)         

public class DBAccess {
	// 构造器私有化,避免外部创建对象
	private DBAccess() {

	}

	// static修饰,保障其能够被静态方法访问
	private final static DBAccess dbAccess = new DBAccess();

	// 外部直接调用静态方法实例化对象
	public static DBAccess getInstance() {
		return dbAccess;
	}
}

     

        2.饿汉式(静态代码块)

class DBAccess2 {
	private DBAccess2() {

	}

	private static DBAccess2 dbAccess = null;

	static {
		dbAccess = new DBAccess2();
	}

	public static DBAccess2 getInstance() {
		return dbAccess;
	}
}

        3.懒汉式(线程不安全)

class DBAccess3 {
	private DBAccess3() {

	}

	private static DBAccess3 dbAccess = null;

	public static DBAccess3 getInstance() {
		if (dbAccess == null) {
			dbAccess = new DBAccess3();
		}
		return dbAccess;
	}
}

        4.懒汉式(线程安全,同步代码块)

class DBAccess4 {
	private DBAccess4() {

	}

	private static DBAccess4 dbAccess = null;

	public static DBAccess4 getInstance() {
		synchronized (DBAccess4.class) {
			if (dbAccess == null) {
				dbAccess = new DBAccess4();
			}
		}
		return dbAccess;
	}
}

        5.懒汉式(线程安全,同步方法)

class DBAccess5 {
	private DBAccess5() {

	}

	private static DBAccess5 dbAccess = null;

	public synchronized static DBAccess5 getInstance() {
		if (dbAccess == null) {
			dbAccess = new DBAccess5();
		}
		return dbAccess;
	}
}

        6.双重检查

class DBAccess6 {
	private DBAccess6() {

	}

	private static DBAccess6 dbAccess = null;

	public static DBAccess6 getInstance() {
		if (dbAccess == null) {
			synchronized (DBAccess6.class) {
				if (dbAccess == null) {
					dbAccess = new DBAccess6();
				}
			}
		}
		return dbAccess;
		// return new DBAccess6();
	}
}

        7.静态内部类

class DBAccess7 {
	private DBAccess7() {

	}

	private static class DBAccess7Instance {
		private static DBAccess7 dbAccess = new DBAccess7();
	}

	public static DBAccess7 getInstance() {
		return DBAccess7Instance.dbAccess;
	}
}

        8.枚举

enum DBAccess8 {
	DBACCESS;
	public static DBAccess8 getInstance() {
		return DBAccess8.DBACCESS;
	}
}
  • 饿汉式和懒汉式的区别

(1)饿汉式和懒汉式的主要区别是他们使用的加载策略不同,饿汉式使用的是立即加载,而懒汉式用的是延迟加载(懒加载)。简单来说就是饿汉式不管你用不用,它都实例了。而懒汉式是当你调用方法时它才去实例。

(2)饿汉式虽存在性能问题,但它是线程安全的,而懒汉式可能存在线程不安全的问题,当然也可以通过同步代码块或同步方法的方式解决,如上面4、5。(注:4比5的性能更好)。

  • 结论:

单例中两种饿汉式可用,但是存在性能问题

单例中三种懒汉式不推荐,存在线程安全问题,同步方法的方式解决了线程的问题,但是性能极差

最后三种单例模式值得推荐

  • 注意事项
    • 系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能

    • 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用 new

  • 应用
    • jdk源码中Runtime类
    • tomcat中ApplicationContext类
    • session 工厂

学习记录,若有错误,欢迎指正,若有疑问,欢迎评论。

求点赞

作者:借我丹青妙笔

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/693765.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号