设计模式----单例模式(饿汉模式、懒汉模式)

JDK1.8  

demo地址:https://gitee.com/aibaguoguo/singleten-demo.git

复习下工厂模式的运用,单例的公共接口

package test;
/**
 * 单例接口
 */
public interface IDemo {
	static IDemo getInstence() {
		return null;
	}
}
1.饿汉单例模式,天生线程安全(最后有测试案例)
package test;


/**
 * 饿汉单例模式
 */
public class DemoHungry implements IDemo{
    //私有化构造器
    private DemoHungry() {}
    
    private final static DemoHungry demo = new DemoHungry();
    
    public static IDemo getInstence() {
        return demo;
    }
}

2.普通懒汉单例模式(线程安全需要加上synchronized关键字)

package test;

/**
 * 普通懒汉单例模式
 */
public class DemoLazy implements IDemo {
	private DemoLazy() {}
	
	private static DemoLazy lazy = null;
	
	//想要线程安全,需要加上synchronized
	public static IDemo getInstence() {
		if(lazy==null) {
			lazy = new DemoLazy();
		}
		return lazy;
	}
}

3.内部类实现懒汉单例(线程安全)

package test;

public class DemoLazyInnerClass implements IDemo {
	
	private DemoLazyInnerClass() {}
	
	/**
	 * 私有化的内部类
	 */
	private static class DemoHolder{
		private static final IDemo demo = new DemoLazyInnerClass();
	}
	
	/**
	 * 返回单例
	 */
	public static final IDemo getInstence() {
		return DemoHolder.demo;
	}
}

单例工厂

package test;

/**
 * 单例工厂类
 */
public class DemoFactory {
	
	/**
	 * 饿汉单例模式
	 */
	public static IDemo getDemoHungry() {
		return DemoHungry.getInstence();
	}
	
	/**
	 * 普通懒汉单例模式
	 */
	public static IDemo getDemoLazy() {
		return DemoLazy.getInstence();
	}
	
	/**
	 *内部类懒汉单例模式
	 */
	public static IDemo getDemoLazyInnerClass() {
		return DemoLazyInnerClass.getInstence();
	}
}

模拟并发测试类

package test;

import java.util.concurrent.CountDownLatch;

/**
 * 并发测试类
 */
public class DemoTest {
	public static void main(String[] args) {
		int count = 200;
		CountDownLatch latch = new CountDownLatch(count);
		
		for(int i=0;i<count;i++) {
			new Thread() {
				@Override
				public void run() {
					try {
						latch.await();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					IDemo demo = DemoFactory.getDemoLazy();//工厂模式获取不同的单例产生方案,测试并发情况下的线程安全问题
					System.out.println(System.currentTimeMillis()+":"+demo);//输出时间和对象地址
				}
			}.start();
			
			latch.countDown();
		}
	}
}

最后测试结果:普通懒汉模式出现了并发问题(如果不加synchronized关键字)



下一篇笔记,注册单例模式、枚举单例模式、单例如何防止反射入侵等等。未完待续.....

 

猜你喜欢

转载自blog.csdn.net/weixin_42334408/article/details/80753635