单例设计模式的二种写法及线程安全的懒汉式写法

单例模式:
单例模式就是采用了一定的方法,保证了再整个系统当中,对某个类的实例对象都只存在唯一的一个。

单例模式的饿汉式和懒汉式写法
饿汉式写法:饿汉式,顾名思义就是很饥饿的意思一上来就创建对象

public class SingletonTest1 {
    public static void main(String[] args)
    {
        SingletonDome1 singletonDome1 = SingletonDome1.singletonDome1;
        SingletonDome1 singletonDome2 = SingletonDome1.singletonDome1;
        System.out.println(singletonDome1==singletonDome2);
    }
}

//  饿汉式,一调用就拿到改对象
class SingletonDome1{
        //  1.  私有化构造器 目的外部无法创建实例
        private SingletonDome1(){}

        //  2.声明当前类的对象为static保证调用的是用一个实例,并初始化对象
        public final static SingletonDome1 singletonDome1=new SingletonDome1();

}

懒汉式写法:懒汉式,证明就是比较懒,需要在使用的时候在创建

public class SingletonTest2 {
    public static void main(String[] args)
    {
  	   SingletonDome2 singletonDome3 = SingletonDome2.getSingletonDome2();
       SingletonDome2 singletonDome4 = SingletonDome2.getSingletonDome2();
        System.out.println(singletonDome3==singletonDome4);
	 }
}

// 懒汉式,需要使用的时候在拿到改对象
class SingletonDome2{
        //  1.  私有化构造器 目的外部无法创建实例
        private SingletonDome2(){}

        //  2.声明当前类的对象为static,不立即创建对象
        private static SingletonDome2 singletonDome2=null;

        //  3.提供外部能获取到私有对象的方法,并且需要使用static来修饰,证明是共享的
        public static SingletonDome2 getSingletonDome2(){
                //  判断是否没有该对象的实例,如果没有就创建,如果有就使用原来的
                if(singletonDome2==null){
                    singletonDome2= new SingletonDome2();
                }
            return singletonDome2;
        }
}

饿汉式和懒汉式的区别:
1.饿汉式的坏处:因为是一调用该方法就创建对象,所以导致了对象创建的时间过长。
2.饿汉式的好处:线程安全
3.懒汉式的好处:延迟创建对象
4.懒汉式的坏处:线程不安全

既然说到懒汉式线程不安全那怎么证明,证明之后怎么样来保证在多线程的情况下保证他线程安全呢?
证明其懒汉式线程不安全

public class SingletonTest2 {
    public static void main(String[] args)
    {
        //  创建二个线程
        Thread thread1=new Thread(){
            @Override
            public void run()
            {
                SingletonDome2 singletonDome3 = SingletonDome2.getSingletonDome2();
                System.out.println("singletonDome3的地址值"+singletonDome3);
            }
        };

        Thread thread2=new Thread(){
            @Override
            public void run()
            {
                SingletonDome2 singletonDome4 = SingletonDome2.getSingletonDome2();
                System.out.println("singletonDome4的地址值"+singletonDome4);
            }
        };

        thread1.start();
        thread2.start();




    }
}

// 懒汉式,需要使用的时候在拿到改对象
class SingletonDome2{
        //  1.  私有化构造器 目的外部无法创建实例
        private SingletonDome2(){}

        //  2.声明当前类的对象为static,不立即创建对象
        private static SingletonDome2 singletonDome2=null;

        //  3.提供外部能获取到私有对象的方法,并且需要使用static来修饰,证明是共享的
        public static SingletonDome2 getSingletonDome2(){

                //  判断是否没有该对象的实例,如果没有就创建,如果有就使用原来的
                if(singletonDome2==null){
                    try
                    {
                        //  让线程休眠 更好看到结果
                        Thread.sleep(100);

                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }

                    singletonDome2= new SingletonDome2();
                }
            return singletonDome2;
        }
}

以上测试代码的运行结果:二个地址值不一致,证明拿到的对象不一致
在这里插入图片描述

懒汉式安全的写法:添加synchronized锁

public class SingletonTest2 {
    public static void main(String[] args)
    {
        //  创建二个线程
        Thread thread1=new Thread(){
            @Override
            public void run()
            {
                SingletonDome2 singletonDome3 = SingletonDome2.getSingletonDome2();
                System.out.println("singletonDome3的地址值"+singletonDome3);
            }
        };

        Thread thread2=new Thread(){
            @Override
            public void run()
            {
                SingletonDome2 singletonDome4 = SingletonDome2.getSingletonDome2();
                System.out.println("singletonDome4的地址值"+singletonDome4);
            }
        };

        thread1.start();
        thread2.start();
    }
}

// 懒汉式,需要使用的时候在拿到改对象
class SingletonDome2{
        //  1.  私有化构造器 目的外部无法创建实例
        private SingletonDome2(){}

        //  2.声明当前类的对象为static,不立即创建对象
        private static SingletonDome2 singletonDome2=null;

        //  3.提供外部能获取到私有对象的方法,并且需要使用static来修饰,证明是共享的
        public static SingletonDome2 getSingletonDome2(){
                //  添加Java自带的锁,锁住该类
                synchronized (SingletonDome2.class)
                {
                    //  判断是否没有该对象的实例,如果没有就创建,如果有就使用原来的
                    if (singletonDome2 == null)
                    {
                        try
                        {
                            //  休眠时间变长,检查是否线程安全
                            Thread.sleep(1000);

                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }

                        singletonDome2 = new SingletonDome2();
                    }
                };
            return singletonDome2;
        }
}

运行结果:多次运行之后得到的结果还是一致的状态,证明拿到的对象是同一个对象
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值