1、饿汉模式
饿汉模式
直接在类加载的时候就创建对象
优点:
线程安全,获取对象效率高
缺点:
占用空间,类加载效率低
public class EHanPattern {
private static final EHanPattern INSTANCE=new EHanPattern();
private EHanPattern(){
}
public static EHanPattern getInstance(){
return INSTANCE;
}
}
需要优化启动速度,我们可以用哪个静态代码块优化,让其在需要的时候创建对象。
public class EHanPatternOptimizing {
private static final EHanPatternOptimizing INSTANCE;
static{
INSTANCE=new EHanPatternOptimizing();
}
private EHanPatternOptimizing(){
}
public static EHanPatternOptimizing getInstance(){
return INSTANCE;
}
}
2、懒汉模式
优点:
节省空间,启动速度快,
缺点:
线程不安全,获取对象效率低
public class LanHanPattern {
private static LanHanPattern instance=null;
private LanHanPattern(){
}
public static LanHanPattern getInstance(){
if(instance==null){
instance=new LanHanPattern();
}
return instance;
}
}
优化:双重校验锁,优化的时线程安全问题
public class LanHanPatternOptimizing {
private static LanHanPatternOptimizing instance=null;
private LanHanPatternOptimizing(){
}
public static LanHanPatternOptimizing getInstance(){
if(instance==null){
try {
synchronized (int.class) {
if(instance==null){
instance= new LanHanPatternOptimizing();
}
}
}
return instance;
}
}
3、多线程测试懒汉到底怎么不安全
改写懒汉模式在其中加入延时方法用于模拟中间有很多代码程序的运行、
public class LanHanPattern {
private static LanHanPattern instance=null;
private LanHanPattern(){
}
public static LanHanPattern getInstance(){
if(instance==null){
try {
Thread.sleep(100); //延时用于模拟中间很多代码
} catch (InterruptedException e) {
e.printStackTrace();
}
instance=new LanHanPattern();
}
return instance;
}
}
创建线程类用于比较创建的单例是否相等
public class SingletonThread extends Thread{
public static LanHanPattern lanhan1;
public static LanHanPattern lanhan2;
@Override
public void run() {
LanHanPattern lanhan1=LanHanPattern.getInstance();
try {
Thread.sleep(100); //延时0.1S
} catch (InterruptedException e) {
e.printStackTrace();
}
LanHanPattern lanhan2=LanHanPattern.getInstance();
if(lanhan1!=null && lanhan2!=null){
if(lanhan1!=lanhan2){
System.out.println("false 线程不安全");
}
}
}
}
只要打印出线程不安全,就说明创建的对象时不等的,下面我们来创建测试类
@Test/*测试懒汉*/
public void testLanHanPattern() {
/*每一次创建10000个线程*/
for(int j=0;j<10000;j++){
new SingletonThread().start();
}
System.out.println("true 线程安全");
}
输出结果:
创建了1w个线程,大概有报了2000多次线程不安全