1-单例模式-常见的设计模式

单例模式
    译:保证整个系统中一个类只有一个对象实例,实现这种功能的方式叫做单例模式。
    白话文:在每次操作中,有且只有一个对象的实例在运行,这种模式可以很方便的共享这个对象资源。
    单例模式分类(饿汉式、懒汉式、静态内部类)
    单例模式的四大原则:
        1:构造私有
        2:以静态方法或者枚举返回实例
        3:确保实例只有一个,尤其是在多线程的环境下
        4:确保反序列化是不会重新构建对象

1:单例模式-饿汉式
    个人理解:饿汉式就是在类创建的时候就一起创建好了,创建好之后就一直在资源堆里面,当饿了(当需要的时候)就可以很快的获取。(空间换时间)
    Demo:

//单例模式-饿汉式
		public class HungryChinese{
			//在类加载时创建对象
			private final static HungryChinese hungry = new HungryChinese();
			//私有化构造器,防止外界创建对象(就是不能new HungryChinese())
			private HungryChinese(){};
			//提供外界获取对象的方法
			public static HungryChinese getHungry (){
				//返回单个实例(返回的始终是同一个实例)
				return hungry;
			}
		}

    优缺点:
        优点:实例在加载时就创建了,所以可以很方便的获取
        缺点:当饿汉式模式下实例数量太多的话,因不是每个实例都时时用到,所以会造成资源浪费,优点不完美咯~

2:单例模式-懒汉式
    个人理解:区别于饿汉式不会在一开始就创建,当需要了的时候再创建,然后创建好之后就跟懒汉式一样了,创建好之后就一直在资源堆里面(时间换空间)
    Demo:

//单例模式-懒汉式
		public class HungryChinese{
			//在需要时创建
			private final static HungryChinese hungry = null;
			//私有化构造器,防止外界创建对象(就是不能new HungryChinese())
			private HungryChinese(){};
			//提供外界获取对象的方法
			public static HungryChinese getHungry (){
				//判断是否已经创建实例,有则返回单个实例(返回的始终是同一个实例)
				if (hungry == null){
					return new HungryChinese();
				}
				return hungry;
			}
		}

    优缺点:
        优点:区别于饿汉式,这样会减少对资源的占用,需要用时才创建
        缺点:懒汉式面临一个问题,当高并发的时候很容易造成线程不安全,在这个时候可以在对外获取的方法上添加 synchronized 加上锁,但是会影响性能的问题~
            Demo:

//单例模式-懒汉式
			public class HungryChinese{
				//在需要时创建
				private final static HungryChinese hungry = null;
				//私有化构造器,防止外界创建对象(就是不能new HungryChinese())
				private HungryChinese(){};
				//提供外界获取对象的方法
				public synchronized HungryChinese getHungry (){
					//判断是否已经创建实例,有则返回单个实例(返回的始终是同一个实例)
					if (hungry == null){
						return new HungryChinese();
					}
					return hungry;
				}
			}

3:单例模式-静态内部类
    个人理解:把实例化放在内部类中,故而加载的时候不会去实例化,只有当要用到的时候再加载,跟饿汉式和懒汉式有区别,放在内部类内,只会被加载一次,线程也安全了,占用资源也小
    Demo:

//单例模式-静态内部类
public class HungryChinese{
	//私有化构造器,防止外界创建对象(就是不能new HungryChinese())
	private HungryChinese(){};
	//内部类
	private static class Chinese{
		public static HungryChinese hungry = new HungryChinese();
	}
	//提供外界获取对象的方法
	public synchronized HungryChinese getHungry (){
		//返回单个实例(返回的始终是同一个实例)
		return Chinese.hungry;
	}
}

    优缺点:
        优点:资源利用率高,自由执行内部类的时候才会被实例化,同时也可以执行其他类的静态方法。
        缺点:静态内部类加载时需要些时间,第一次反应时间不够快

4:工作中常用的
    个人理解:在工作中,用得比较多的是饿汉式,可以直接获取,如果对资源比较看重的情况下,可以使用静态内部类的方式。

5:扩展(下面一段是copy大神的,我也就理解了哈哈哈~)
    类加载时机:JAVA虚拟机在有且仅有的5种场景下会对类进行初始化。              

 1.遇到new、getstatic、setstatic或者invokestatic这4个字节码指令时,对应的java代码场景为:new一个关键字或者一个实例化对象时、读取或设置一个静态字段时(final修饰、已在编译期把结果放入常量池的除外)、调用一个类的静态方法时。
    2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没进行初始化,需要先调用其初始化方法进行初始化。
    3.当初始化一个类时,如果其父类还未进行初始化,会先触发其父类的初始化。
    4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的类),虚拟机会先初始化这个类。    5.当使用JDK1.7等动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。
    这5种情况被称为是类的主动引用,注意,这里《虚拟机规范》中使用的限定词是"有且仅有",那么,除此之外的所有引用类都不会对类进行初始化,称为被动引用。静态内部类就属于被动引用的行列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值