JavaSE复习——单例模式

单例模式是指,某个类只能被实例化一次,在JVM中,只能有一个相应的对象存在。

第一种实现方式:饿汉式

 

package hungry;

public class HungryMode {
	private HungryMode(){
		//构造方法私有,以防外部通过new来实例化
	}
	
	private static HungryMode instance = new HungryMode(); //准备一个该类的实例化对象,因为在类中定义,所以只有一个该对象。
	
	public static HungryMode getInstance(){
		return instance; //让调用者通过静态方法即可调用定义好的instance
	}
}
package hungry;

public class Test {
	public static void main(String[] args){
		HungryMode hm1 = HungryMode.getInstance();
		HungryMode hm2 = HungryMode.getInstance();
		HungryMode hm3 = HungryMode.getInstance();
		
		System.out.println(hm1==hm2);
		System.out.println(hm2==hm3);
		System.out.println(hm3==hm1);
	}
}

第二种实现方式:懒汉式

懒汉式写法只适用于单线程模式。如果执行到类方法中的if(instance == null),很有可能其他线程也进行到这里并同时实例化出新的FullMode类对象。这不符合单例模式要求,故只能只用于单线程。

也可通过加synchronized关键字解决,但降低了效率。

package full;

public class FullMode {
	private FullMode(){
		
	}
	
	private static FullMode instance;
	
	public static FullMode getInstance(){
		if(instance == null){
			instance = new FullMode();
		}//只有当外部其他类调用本类的static方法时,才实例化出一个对象。之后再调用,都返回这唯一一个对象。
		return instance;
	}
}
package full;

public class Test {
	public static void main(String[] args){
		FullMode fm1 = FullMode.getInstance();
		FullMode fm2 = FullMode.getInstance();
		FullMode fm3 = FullMode.getInstance();
		
		System.out.println(fm1 == fm2);
		System.out.println(fm2 == fm3);
		System.out.println(fm3 == fm1);
	}
}

第三种实现方式:双检查

第一次进行判空,使得同一时刻只能有一个线程进入synchronized区域。第二次判空,如果instance是null,则线程就实例化一个类对象instance。如果不为null,则直接返回已经实例化的instance。适合多线程情况。

package full;

import java.io.File;

public class Test2 {
	public static void main(String[] args){
		
		Th1 t1 = new Th1();
		t1.start();
		
		Th2 t2 = new Th2();
		t2.start();
		
		Th3 t3 = new Th3();
		t3.start();
		
		System.out.println(t1.fm21);
		System.out.println(t2.fm22);
		System.out.println(t3.fm23);
		
		
	}
}
package full;

public class Th1 extends Thread{
	static FullMode2 fm21;
	public void  run(){
		fm21 = FullMode2.getInstance();
	}
	
}
package full;

public class Th2 extends Thread{
	static FullMode2 fm22;
	public void run(){
		fm22 = FullMode2.getInstance();
	}
}
package full;

public class Th3 extends Thread{
	static FullMode2 fm23;
	public void run(){
		fm23 = FullMode2.getInstance();
	}
}
package full;

public class FullMode2 {
	private static volatile FullMode2 instance;
	
	private FullMode2(){
		
	}
	
	public static FullMode2 getInstance(){
		if(instance == null){
			synchronized(FullMode2.class){
				if(instance == null){
					instance = new FullMode2();
				}
			}
		}
		
		return instance;
	}
}

第四种实现方式:静态内部类

类的静态属性只会在第一次加载类的时候被初始化。这里的线程安全由JVM来保障。在类进行初始化时,其他线程无法进入。

package StaticInnerClass;

public class staticInnerMode {
	private staticInnerMode(){
		
	}
	
	private static class SingletonInstance{
		private static final staticInnerMode instance = new staticInnerMode();
	}
	
	public static staticInnerMode getInstance(){
		return SingletonInstance.instance;
	}
}
package StaticInnerClass;

public class Test {
	public static void main(String[] args){
		staticInnerMode s1 = staticInnerMode.getInstance();
		staticInnerMode s2 = staticInnerMode.getInstance();
		staticInnerMode s3 = staticInnerMode.getInstance();
		
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
	}
}

 第五种实现方式:枚举

package enumMode;

public enum SingletonEnum {
	INSTANCE;
	
	int i = 0;
	public void screen(){
		System.out.println("第"+(++i)+"次调用单例对象");
	}
}
package enumMode;

public class Test {
	public static void main(String[] args){
		SingletonEnum se1 = SingletonEnum.INSTANCE;
		SingletonEnum se2 = SingletonEnum.INSTANCE;
		SingletonEnum se3 = SingletonEnum.INSTANCE;
		
		System.out.println(se1);
		se1.screen();
		
		System.out.println(se2);
		se2.screen();
		
		System.out.println(se3);
		se3.screen();
		
	}
}

 通过底层保证了单例的实现,且防止了反序列化。。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值