对比两种单列设计模型(懒汉、饿汉)

1.饿汉式

立即加载,随着类而加载创建

优点:写法简单、在内存中加载较早,使用起来方便安全。而且线程是安全的。

缺点:在内存中占用时间长

public class danxiancheng {
    public static void main(String[] args) {
        gril aa = gril.getBank();
        System.out.println(aa.a);
        gril bb =gril.getBank();

    }
}
class gril{
    int a;
    private gril() {
    }
    private static gril bank = new gril();//饿汉式
    public static gril getBank(){
        return bank;
    }

}

 线程安全测试:

class test{
        static man m1 = null;
        static man m2 = null;
    public static void main(String[] args) {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                m1 =man.getM1();
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                m2=man.getM1();
            }
        };
        t1.start();
        t2.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(m1);
        System.out.println(m2);
        System.out.println(m1 == m2);
    }
}
class man{
    private static man m1 = new  man();//饿汉式,提前实例化man对象,并且唯一

    static man getM1() {
        return m1;
    }
}

 运行结果:

chapter_9.man@1b6d3586
chapter_9.man@1b6d3586
true

2.懒汉式

延迟加载,在需要的时候加载创建

优点:在需要的时候创建,节省了内存空间

缺点:线程不安全

public class danxiancheng {
    public static void main(String[] args) {
        gril a1 = null;
        gril aa= gril.getbank(a1);
        System.out.println(aa);
    }
}
class gril{
    int a;
    //构造器私有化
    private gril() {
    }
    //声明当前类的实列
    private gril bank =null;
    //通过getbank获得当前类的实列,如果为null对当前类实列话,否则返回当前类实列
    public static gril getbank(gril cbank){
        if(cbank == null){
            cbank = new gril();
        }
        return cbank;
    }
}

线程安全测试:

class test{
    static man m1 =null;
    static man m2 =null;
    public static void main(String[] args) {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                m1 = man.getM1();
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                m2 = man.getM1();
            }
        };
        t1.start();
        t2.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(m1);
        System.out.println(m2);
        System.out.println(m1 == m2);
    }
}
class man{
    private static man m1 =null;
    static man getM1() {
        if(m1 == null){
            m1 = new man();
        }
        return m1;
    }
}

测试结果:

chapter_9.man@1b6d3586
chapter_9.man@4554617c
false 

 解决方法:synchronized同步

static synchronized man getM1() {//关注this是否唯一,此时有statci,所以man.class唯一
        if(m1 == null){
            m1 = new man();
        }
        return m1;
    }

or


    static man getM1() {
        synchronized (man.class) {
            if(m1 == null){
                m1 = new man();
            }
            return m1;
        }
    }

//相比以上优化
private static volatile man m1 =null;//为了避免指令重排,使用volatile声明m1

or//加入lock

lock.lock();
if(m1 == null){
            m1 = new man();
        }
        return m1;

lock.unlock();
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值