【Java】线程同步 & 单例设计模式应用 & double check

单例设计模式--->确保一个类只有一个对象

懒汉式单例模式

  1. 构造器私有化,避免外部直接创建对象
  2. 声明一个私有的静态变量
  3. 创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
package TreadLearning;

import org.omg.CORBA.SystemException;

/**
 * 单列设计模式:确保一个类只有一个对象
 * 
 * @author 袁盛桐
 *
 */
public class synsingle {
	public static void main(String[] args) {
		//创建两个线程,启动后由于jvm中的getinstance方法是synchronized
		//所以第一个线程进去后先创建一个实例,执行结束后
		//第二个线程才可以进入方法,由于第一个线程已经创建实例,所以直接返回,故是同一对象
		jvmthread demo1 = new jvmthread();
		jvmthread demo2 = new jvmthread();
		
		demo1.start();
		demo2.start();
	}
}

class jvmthread extends Thread{
	
	public jvmthread() {
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+"-->create"+jvm.getInstance());
	}
	
	
}
/**
 * 单利设计模式
 * 确保一个类只有一个对象
 * 懒汉式
 * 1.构造器私有化,避免外部直接创建对象
 * 2.声明一个私有的静态变量
 * 3.创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
 */
class jvm{
	//声明一个私有的静态变量
	private static jvm instance = null;
	
	//构造器私有化,避免外部直接创建对象
	private jvm() {
		
	}
	
	//创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
	public static synchronized jvm getInstance() {
		
		if(null == instance) {
			instance = new jvm();
		}
		
		return instance;
	}
}

由于创建两个线程,启动后由于jvm中的getinstance方法是synchronized,所以第一个线程进去后先创建一个实例,执行结束后第二个线程才可以进入方法,由于第一个线程已经创建实力,所以直接返回,故是同一对象

上述线程安全采用的式同步方法,下面采用同步代码块 并且采用3层检查double check方式

double check详解--->提高效率

//创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
	public static jvm getInstance() {
		//在外面再加一层判断为了提高效率,如果存在实例直接返回
		if(null == instance) {
			//对jvm上锁,利用jvm的字节码,相当于类模板锁住,不能再继续创建新的类实例了
			synchronized(jvm.class) {
				if(null == instance) {
					instance = new jvm();
				}	
			}
		}
		return instance;
	}

 假设有thread a 和 thread b 和 thread c

  1. a 和 b 同时创建,进入第一层if判断,结果instance为空,都进入第二层
  2. 在第二层由于对jvm.class是synchronized,所以a 先进入第二层,b等候
  3. a进入第二层后发现instace为空,创建instance然后返回
  4. b进入第二层发现instance不为空,直接跳出第三层if判断,返回instance
  5. 这时候c创建,在第一层时候直接判断instance不为空,直接返回instance,节约了时间

猜你喜欢

转载自blog.csdn.net/weixin_38516944/article/details/82115152
今日推荐