单例模式(饿汉方式懒汉方式)

Posted 秃头小宝儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式(饿汉方式懒汉方式)相关的知识,希望对你有一定的参考价值。


单例模式:全局唯一并且所有程序都可以使用的对象,就是单例模式。

1.饿汉方式(线程安全的)

(1)代码实现

public class ThreadDemo84 {
    //单例类
    static class Singleton{
        //1.将构造函数设置为私有的(不让外部常见)
        private Singleton(){
        }

        //2.创建一个静态的类变量(让底下第三步方法返回的)
        private static Singleton singleton=new Singleton();

        //3.给外部接口提供的获取单例的方法
        public static Singleton getInstance(){
            return singleton;
        }
    }
    static Singleton s1=null;
    static Singleton s2=null;
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                s1=Singleton.getInstance();
            }
        })  ;
        Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                s2=Singleton.getInstance();
            }
        });
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println(s1.equals(s2));
    }
}

(2)饿汉方式的优缺点

优点

实现简单、不存在线程安全的问题,因为饿汉的方式是随着程序的启动而初始化的,因为类加载是线程安全的,所以他是线程安全的。

缺点

随着程序的启动而启动,有可能在整个程序的运行周期里面都没有用到,这样就带来了没有必要的开销。

2.懒汉方式

(1)代码实现

①懒汉实现版本一(非线程安全的)

//1.设置私有的构造函数
    static class Singleton{
    }
    //2.创建一个静态的类变量
    private static Singleton singleton=null;
    //3.提供给外部调用(返回一个单例对象给外部)
    public static Singleton getInstance(){
        if(singleton==null){
            //第一次访问,进行实例化
            singleton=new Singleton();
        }
        return singleton;
    }

②版本二:可以保证线程安全,锁粒度太多,性能不高

public static Singleton getInstance() throws InterruptedException {
        if(singleton==null){
            Thread.sleep(1000);
            //第一次访问,进行实例化
            singleton=new Singleton();
        }
        return singleton;
    }

③双重校验锁

在这里插入图片描述

④防止指令重排序

//1.设置私有的构造函数
    static class Singleton{
    }
    //2.创建一个静态的类变量(volatile)
    private static volatile Singleton singleton=null;
    //3.提供给外部调用的方法
    public static Singleton getIntance(){
        if(singleton==null){
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            synchronized (Singleton.class){
                if(singleton==null){
                    singleton=new Singleton();
                }
            }
        }
        return singleton;
    }

以上是关于单例模式(饿汉方式懒汉方式)的主要内容,如果未能解决你的问题,请参考以下文章

单例模式(饿汉方式懒汉方式)

单例模式(饿汉方式懒汉方式)

多线程案例 --- 单例模式(饿汉懒汉)阻塞式队列

设计模式之单例模式--懒汉模式与饿汉模式

单例模式:饿汉式与懒汉式

线程池 线程安全的单例模式 饿汉方式 懒汉方式