设计模式笔记——单例模式

前几天校园招聘会,投简历时就直接给我来了一份笔试题。我一看,卧槽,全都是考很基本很基本的题,可以说基本到恶心,然而对于我这个实习了半年,可以独自把一个项目完成的程序猿来说,很可惜这些基本题却把我放倒了,真是讽刺啊。就感觉一个全栈工程师被问如何输出一个helloworld被吓得跪地直喊OMG一样,哈哈,开个玩笑。没办法,面向学生招聘,企业都爱玩这一套,对于我这个有实战经验的人来说,尽管这些基本的东西感觉在实际项目还真不怎么用得上,但还是得去沉淀一下啊。

笔试题的组成基本少不了数据结构和设计模式,既然你把我放倒了,那么我就从设计模式开始补回来吧,坚持一天一种模式学习吧。

首先是设计模式里最简单的一种模式,单例模式。顾名思义,就是一个类,在使用的时候确保只有一个实例被初始化。

第一步,创建一个单例类:

SingleTon.java

public class SingleTon {

	private static SingleTon instance;
	
	private int count;
	
	//构造方法为私有,无法直接new()获得实例
	private SingleTon(){
		count=0;
	}
	
	public static SingleTon getInstance(){
		if(instance==null){
			instance=new SingleTon();
		}
		return instance;
	}
	
	public void print(){
		System.out.println(count);
	}
	
	public void add(){
		System.out.println("变量加1");
		count++;
	}
	
}


第二步,创建一个运行测试类:

PatternTest.java

public class PatternTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		SingleTon singleTon1=SingleTon.getInstance();
		singleTon1.print();
		singleTon1.add();
		
		SingleTon singleTon2=SingleTon.getInstance();
		singleTon2.print();
		
	}

}


运行结果:

设计模式笔记——单例模式_第1张图片


果然很简单吧,两次获取实例都是同一个实例,所以加一操作add()也只是在同一个对象上的成员变量加一。


不过,对于单例模式,若是比较起其性能,如内存,线程安全等,则有几种不同的实现方式。

1.  节省内存(懒汉模式),非线程安全式:

public class SingleTon {

	private static SingleTon instance;
	
	//构造方法为私有,无法直接new()获得实例
	private SingleTon(){}
	
	public static SingleTon getInstance(){
		if(instance==null){
			instance=new SingleTon();
		}
		
		return instance;
	}
	
	
}
实际上就和上面一开始的代码一样,只有使用时才实例化,但没有考虑到线程安全。


2. 节省内存, 线程安全,效率慢式:

public class SingleTon {

	private static SingleTon instance;
	
	//构造方法为私有,无法直接new()获得实例
	private SingleTon(){}
	
	public static synchronized SingleTon getInstance(){
		if(instance==null){
			instance=new SingleTon();
		}
		
		return instance;
	}
	
	
}
就是在getInstance()方法里加个同步锁而已,虽然可以达到线程安全,但效率慢。


3. 耗内存,线程安全,效率快式:

public class SingleTon {

	private static SingleTon instance=new SingleTon();
	
	//构造方法为私有,无法直接new()获得实例
	private SingleTon(){}
	
	public static SingleTon getInstance(){
		return instance;
	}
	
	
}
就直接在加载类的时候就初始化了,这样会耗内存,但不使用synchronize锁,这样就可以不用加同步锁也可以达到线程安全的效果。


实际上还有其他的方式,但一般都是使用第三种方式创建单例多。






你可能感兴趣的:(设计模式)