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关键字)
下一篇笔记,注册单例模式、枚举单例模式、单例如何防止反射入侵等等。未完待续.....