java单例设计模式

什么是单例设计模式

单例即只有一个实例,该模式的作用是保证程序中某个类的对象只有一个。

单例模式分为懒汉式和饿汉式。

懒汉式

class Student{
	static Student st;
	private Student(){}
	public static Student getInstance(){
		//引用数据类型属性在内存中的默认值为null
		//如果值为null 只创建一次对象
		if(st==null){
			st = new Student();
		}
		return st;
	}
}

public class Test1 {
	
	public static void main(String[] args) {
		// 利用hascode 相等 是单例  
		Student tes1 = Student.getInstance();
		System.out.println(tes1.hashCode());
		
		Student tes2 = Student.getInstance();
		System.out.println(tes2.hashCode());
	}
}

 以上可以看出结果的hasCode值是相同的只创建了一个对象

但是这种模式在多线程的情况下会产生线程安全问题:

class Teacher{
	static Teacher s;
	private Teacher(){}
	public static Teacher getInstance(){
		if(s == null){
			s = new Teacher();
		}
		return s;
	}
}

class StudentThread extends Thread{
	public void run(){
		for(int i = 0;i<3;i++){
				Teacher ss = Teacher.getInstance();
				System.out.println(ss.hashCode());
		}
	}
}

public class Test2 {
	public static void main(String[] args) {
		//单例模式在多线程中存在线程安全问题  需要解决线程安全
		//创建线程
		StudentThread tt1 = new StudentThread();
		StudentThread tt2 = new StudentThread();
		//就绪状态
		tt1.start();
		tt2.start();
	}
}

 如果在运行多次的情况下会出现hasCode不一定都一样  这就出现了线程安全问题:

解决办法只需要将返回对象的方法设置为同步方法即可

public synchronized static Teacher getInstance(){
		if(s == null){
			s = new Teacher();
		}
		return s;
	}

 饿汉式

//饿汉式
class Hangle{
	//创建静态属性的时候就赋值  并且只执行一次  也就是说只创建一次对象
	static Hangle ha = new Hangle();
	public static Hangle getInstance(){
		return ha;
	}
}

class SingleThread extends Thread{
	public void run(){
		for(int i = 0;i<4;i++){
			Hangle hh = Hangle.ha;
			System.out.println(hh.hashCode());
		}
	}
}

public class Test3 {
	public static void main(String[] args) {
		SingleThread tt1 = new SingleThread();
		SingleThread tt2 = new SingleThread();
		
		//就绪状态
		tt1.start();
		tt2.start();
		
		// 总结: 懒汉式 在多线程环境中会发生线程安全问题 (可以解决线程问题)
		//而饿汉式不管是在单线程还是在多线程中 不存在线程安全问题  建议定义单例模式的话 用饿汉式
		//饿汉式单例模式要比懒汉式效率高
	}
}

猜你喜欢

转载自www.cnblogs.com/nianzhilian/p/9108589.html