zoukankan      html  css  js  c++  java
  • 单例模式

    饿汉式,使用static final修饰,类初始化的时候创建对象,之后操作的都是听一个对象,因此不存在线程安全问题

    public class Person {
        //饿汉式(多线程也是单例)
        public static final Person PERSON = new Person();
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private Person() {
        }
    
        //提供一个全局静态方法
        public static Person getPerson() {
            return PERSON;
        }
    }
    View Code

    懒汉式,调用的时候才会创建对象,当多线程调用实例方法的时候,由于不存在同步锁,可能进入getPerson()内部,因此无法保证线程安全

    public class Person2 {
        private String name;
        //懒汉式(多线程不是保证单例)
        private static Person2 person2;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private Person2() {
        }
    
        //提供一个全局静态方法
        public static Person2 getPerson() {
            if (person2 == null) {
                return new Person2();
            }
            return person2;
        }
    }
    View Code

    饿汉式保证线程安全的方式,在实例方法上添加同步锁,是其它线程无法调用整个实例方法

    public class Person3 {
        private String name;
        //懒汉式(多线程不是保证单例,加锁)
        private static Person3 person3;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private Person3() {
        }
    
        //提供一个全局静态方法
        public static synchronized Person3 getPerson() {
            if (person3 == null) {
                return new Person3();
            }
            return person3;
        }
    }
    View Code

    双重检查实现饿汉式线程安全改进,由于在整个方法块加锁,验证浪费线程资源,缩小锁范围,仅仅在创建实例对象的时候加锁,但由于进入对象为null的时候可能有多线程进入,因此需要重复判断,双重检查

    public class Person4 {
        private String name;
        //(双重检查)
        private static Person4 person4;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private Person4() {
        }
    
        //提供一个全局静态方法
        public static Person4 getPerson() {
            if (person4 == null) {//可能有+进入到这一块
                synchronized (Person4.class) {
                    if (person4 == null) {
                        person4 = new Person4();
                    }
                }
            }
            return person4;
        }
    }
    View Code

    小结:饿汉式代码实现简单,线程安全,但是不支持延迟加载,空间消耗大;

    懒汉式实现也相对简单,但是不能满足多线程安全问题,添加同步锁也是不错的,支持延迟加载,即用即创建;

    双重检查实现相比之下的确复杂不少,但是相对于懒汉式的同步方法锁,效率的确提高了不少,还节省了空间。

  • 相关阅读:
    C++11 二叉堆
    OpenCV --- 实现两幅图像并排合并(ROI)
    OpenCV --- 修改图像的对比度、亮度 、RGB转Gray图像、修改图像的尺寸
    Opencv --- 图像像素遍历的各种方法
    Ubuntu系统的安装(虚拟机) 并配置C/C++编译器
    在Ubuntu下编译安装nginx
    【OpenCV3】threshold()函数详解
    MFC 剪切板的使用、线程介绍
    C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构
    【OpenCV3】cvRound()、cvFloor()、cvCeil()函数详解
  • 原文地址:https://www.cnblogs.com/shun998/p/12690361.html
Copyright © 2011-2022 走看看