设计模式--单例模式

单例模式:

  1. 饿汉式
  2. 懒汉式

单例模式属于 设计模式的 创建型模式

1.普通实例类:

class Apple{

	public void Apple(){
		system.out.printf("This is apple instance");
	}

	public   void eat(){
		system.out.printf("Apple  eat");
	}

}


class Test {
	public void main(string args[]){
		Apple apple=new apple();
		apple.eat();
	}

}

单例模式:

2 . 饿汉式

class Apple{
	private  static apple=new Apple();

	private Apple(){};
	

	public void eat(){
		system.out.printf("apple eat");
	}

	public static Apple  getInstance(){
		return apple;
	}

}

class Test{

	public void  main(string args[]){
		Apple apple=Apple.getInstance();
		apple.eat();
	}

}

3.懒汉式

class Apple {
		private static Apple  apple=null;
		
		private Apple(){};
		public void eat(){
			system.out.printf("apple eat");
		}
		public static Apple getInstance(){
			if(apple ==null){
				apple=new Apple();
			}
			return apple;
		}
}

class Test{
		public void main(string args[]){
			Apple apple=Apple.getInstance();
			apple.eat();
		}
}

以上是 理解单例模式的简单例子。 1 普通实例类 2 饿汉式 3 懒汉式
一下简称 1 2 3
2 实例化类使用的是 静态变量。 是类共享的。 但是 2 3 也是有区别的 2 是线程安全的

但是3 呢? 难道就没有用了吗? 并不是, 我们在实际使用时候,有时要在类实例化的时候,进行一些操作, 显然2 是很难实现的 3 就能很好的实现。

1 和 2 3 的区别 2,3 中类的构造方法是私有的也就意味着, 2 3 是没有 像 1 中那样 new 实例的。

现在让我们来看看 如何使 3 线程安全

4.1 懒汉式线程安全 1.0v

class Apple{
	 private static Apple  apple=null;
		
	private Apple(){};
	public void eat(){
		system.out.printf("apple eat");
	}
	public static Apple getInstance(){
		
		if(apple ==null){
			synchronized(Apple.class){
				apple=new Apple();
			}	
		}	
		return apple;
	}
	

}

//以下的测试和这个test一样,不再进行测试代码的 
class Test{
		public void main(string args[]){
				Apple apple=Apple.getInstance();
				apple.eat();
		}		
}

4.1 只会使 要实例的代码 变成 排队等待 new ,这么和我们的初衷是有出入的。 但是这个 和3 相比已经有进步,考虑到了 线程安全问题, 这不就是 软件 升级迭代的过程吗?也就像我们的成长,每次回首过去,不禁羞愧可笑,但这不就证明这我们的成长吗? 没有开始就十全十美只有在不停的使用中,进行升级迭代。 前提 每个版本都可用啊。

4.2 懒汉式 线程安全 4.2v

class Apple{
	private static Apple apple=null;
	private Apple(){};

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

	}	

}

4.2 这样就可以防止 4.1的问题了。 江湖称这种做法叫 双重检查 double-check.
但是jvm 会对 我们的代码进行 指令排序优化。 会破坏我们想做的。

4.3 懒汉式线程安全 4.3v

 class Apple{
		private  volatile  static Apple=null;
		private Apple(){};
		public void eat(){
			system.out.printf("apple eat");
		}
		public static Apple getInstance(){
			synchronized(Apple.class){
				if(apple ==null){
					synchronized(Apple.class){
						apple=new Apple();
					}
				}
			}	
		}
}

volatile 会禁止 jvm 进行 指令排序优化 但是 volatile 是jdk1.5之后实现的,也就是意味这 是依赖jdk 。 不是普世的。

懒汉式2看起来 太过麻烦,既然 饿汉式2是线程安全的,那我们能否使 饿汉式2 在实例之前做一些事情呢? 答案是可以的。

5.1 饿汉式 简化的实现方式


class Apple{
	private static  class AppleBuild{
		private static Apple apple=new Apple();
	}
	private Apple (){};
	
	public void eat(){
		system.out.printf("apple eat");
	}

	public static  Apple getInstance(){
		return AppleBuild.apple;
	}	

}

5.1 和 4.3 实现的功能是相同的,而且更加简化并且不依赖jdk.

参考:
http://www.10tiao.com/html/151/201702/2665513512/1.html 推荐新手可以关注下这个公众号,写的很有趣味。
http://coolshell.cn/articles/265.html
http://www.javatpoint.com/singleton-design-pattern-in-java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值