单例模式 --- 生产环境怎么写

简介: 单例模式 --- 生产环境怎么写

大家好,我是JavaPub!

最近各大互联网公司都传出裁员消息,各个自媒体更是跟风传着各种小道消息,好像寒冬马上要侵蚀整个IT行业。我认为作为提高生产力的技术,永远都会走在发展的最前沿。作为一个技术人,打铁还要自身硬。

1. 当被问到你知道哪些设计模式?
2. 你在代码使用了那些设计模式?
3. 你是怎么怎么使用的?

单例模式是最常见的设计模式之一

相信没有一个攻城狮不懂单例模式,本篇介绍如何在生产环境使用单例模式

为什么使用单例模式

对于软件系统的某些类,它可能是全局使用,无需频繁创建销毁。例如创建、销毁代价比较大的数据库连接,会浪费大量资源。

单例最有代表就是我们耳熟能详的 windows 任务管理器,无论我们创建多少次,总是打开一个窗口。1. 如果打开多个重复的窗口,那就是对资源的浪费,资源是宝贵的。2. 多个窗口还要保证一致性,否则谁也不知道谁对谁错。

所以,就有个单例模式的用武之地

实现

定义:确保一个类只有一个实例,并提供一个全局访问点。

单例模式又可以分为预加载和懒加载。当然我们在生产环境中一般使用较多的是 线程安全+懒加载。下文会提及单例的演变过程,你可以直接看最后一个案例,快速掌握生产环境中实战要点。JavaPub为金九银十助力,淦

预加载
package com.javapub.schema;

/**
 * 预加载 单例模式
 * JavaPub
 */
public class PreloadSingleton {

    public static PreloadSingleton instance = new PreloadSingleton();

    // 其他的类无法实例化单例类的对象
    private PreloadSingleton() {
    }

    public static PreloadSingleton getInstance() {
        return instance;
    }
}

上面这种写法可以保证线程安全。

但是对象还没有使用时就被创建,很明显这种写法会造成资源浪费。

懒加载
package com.javapub.schema;

/**
 * 懒加载 单例模式
 * JavaPub
 */
public class LazyLoadingSingleton {

    private static LazyLoadingSingleton instance = null;

    private LazyLoadingSingleton() {
    }

    public static LazyLoadingSingleton getInstance() {
        if (instance == null) {
            instance = new LazyLoadingSingleton();
        }
        return instance;
    }
}


懒加载显然是不能保证线程安全的,在Java实例化对象会分为三步,JVM为了提高程序执行性能,会对没有依赖关系的代码进行重排序

  1. 初始化内存空间
  2. 初始化对象
  3. 设置instance实例指向刚分配的内存空间

Java

懒加载+线程安全

synchronized 关键字是我们处理线程安全的一个利器,加载 getInstace() 函数可以保证线程安全。但是,如果要经常的调用 getInstance() 方法,不管有没有初始化实例,都会唤醒和阻塞线程。为了避免线程的上下文切换消耗大量时间,如果对象已经实例化了,我们没有必要再使用 synchronized 加锁,直接返回对象。经过如上分析

Sychronized

如上分析,我们把锁加在 if (instance == null) 里面,保证instance未实例化的时候才加锁

package com.javapub.schema;

/**
 * 单例模式 线程安全
 * JavaPub
 */
public class SychronizedSingleton {
    private static SychronizedSingleton instance = null;

    private SychronizedSingleton() {
    }

    public static synchronized SychronizedSingleton getInstance() {
        if (instance == null) {
            synchronized (SychronizedSingleton.class) {
                if (instance == null) {
                    instance = new SychronizedSingleton();
                }
            }
        }
        return instance;
    }
}
Sychronized + Volatile

上面我们了解过,Java 在 new 一个对象是无法保证顺序性的。因此我们需要另一个关键字Volatile保证对象实例化过程中的顺序性。

package com.javapub.schema;

/**
 * 单例模式 线程安全 synchronized volatile
 * JavaPub
 */
public class Singleton {
    private static volatile Singleton instance = null;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

本文主要讨论单例模式,如果你对 volatile、synchronized、Java重排序 等知识点理解模糊,

网络讲解设计模式的文章有很多,但是真正在生产环境中怎么用确一直不被大多数人掌握,所以最近想更新一个系列文章,专门针对设计模式在生产环境怎么用,让更多攻城狮在极客之路提供一点点思路。— JavaPub 一名从服务端转行大数据的工程师

目录
相关文章
|
4月前
|
敏捷开发 设计模式 C语言
软件工程师,要么不写代码,要么就写优雅的代码
软件工程师,要么不写代码,要么就写优雅的代码
48 7
|
5月前
|
SQL Java 测试技术
SpringBoot单元测试快速写法问题之PorkService 接口中的 getPork 方法的作用如何解决
SpringBoot单元测试快速写法问题之PorkService 接口中的 getPork 方法的作用如何解决
|
5月前
|
Java 测试技术 Spring
单元测试问题之在 JCode5 类中使用 testService如何解决
单元测试问题之在 JCode5 类中使用 testService如何解决
38 2
|
5月前
|
Java 测试技术 API
SpringBoot单元测试快速写法问题之创建 PorkInst 实例如何解决
SpringBoot单元测试快速写法问题之创建 PorkInst 实例如何解决
|
6月前
|
测试技术
详解单元测试问题之@InjectMocks注解的执行逻辑如何解决
详解单元测试问题之@InjectMocks注解的执行逻辑如何解决
121 1
|
6月前
|
数据库
代码的应用重构问题之BaseActivity类的主要功能问题如何解决
代码的应用重构问题之BaseActivity类的主要功能问题如何解决
方法的概念理解和demo
方法的概念理解和demo
76 0
|
XML Java 测试技术
JVM && 软件测试的目的和原则 && Spring基本概念 && 项目创建 && 软件测试的生命周期 && SpringBoot创建和运行 && Bean作用域
JVM && 软件测试的目的和原则 && Spring基本概念 && 项目创建 && 软件测试的生命周期 && SpringBoot创建和运行 && Bean作用域
101 0
|
安全 Java 测试技术
工作中单例模式用法及其使用场景?
工作中单例模式用法及其使用场景?
110 0
|
测试技术
测试中进行断言是什么意思?底层原理是什么?
测试中进行断言是什么意思?底层原理是什么?
1469 0

热门文章

最新文章