懒汉式单例

简单版本

public class Single1 {
private static Single1 instance;
private Single1() {}
public static Single1 getInstance() {
if (instance == null) {
instance = new Single1();
}
return instance;
}
}

缺点:多线程下能够创建多个实例

synchronized版本

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

缺点:给方法加锁,对程序执行效率造成负面影响

双重检查(Double-Check)版本

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

缺点:new Single3()由于编译器的优化,指令重排,还是可能出问题

volatile

public class Single4 {

    private static volatile Single4 instance;

    private Single4() {}

    public static Single4 getInstance() {

        if (instance == null) {

            synchronized (Single4.class) {

                if (instance == null) {

                    instance = new Single4();

                }

            }

        }

        return instance;

    }

}

volatile禁止指令重排

饿汉式单例

实现1

public class SingleB {

    private static final SingleB INSTANCE = new SingleB();

    private SingleB() {}

    public static SingleB getInstance() {

        return INSTANCE;

    }

}

缺点:无法掌握INSTANCE初始化时机,如果依赖其他数据,很难保证其他数据在INSTANCE初始化前准备好。

其他实现方式

静态内部类-Effective Java

public class Singleton {

    private static class SingletonHolder {

        private static final Singleton INSTANCE = new Singleton();

    }

    private Singleton (){}

    public static final Singleton getInstance() {

        return SingletonHolder.INSTANCE;

    }

}
  • 对于内部类SingletonHolder,它是一个饿汉式的单例实现,在SingletonHolder初始化的时候会由ClassLoader来保证同步,使INSTANCE是一个真·单例。

  • 同时,由于SingletonHolder是一个内部类,只在外部类的Singleton的getInstance()中被使用,所以它被加载的时机也就是在getInstance()方法第一次被调用的时候。

枚举-Effective Java2

public enum SingleInstance {

    INSTANCE;

    public void fun1() { 

        // do something

    }

}

// 使用

SingleInstance.INSTANCE.fun1();

缺点:在需要继承的场景不适用。

来源: 在java中写出完美的单例模式-風の嵂菄

Java中单例模式的几种实现的更多相关文章

  1. JAVA中单例模式的几种实现方式

    1 线程不安全的实现方法 首先介绍java中最基本的单例模式实现方式,我们可以在一些初级的java书中看到.这种实现方法不是线程安全的,所以在项目实践中如果涉及到线程安全就不会使用这种方式.但是如果不 ...

  2. 设计模式 - Java中单例模式的6种写法及优缺点对比

    目录 1 为什么要用单例模式 1.1 什么是单例模式 1.2 单例模式的思路和优势 2 写法① - 饥饿模式 2.1 代码示例 2.2 优缺点比较 3 写法② - 懒惰模式 3.1 代码示例 3.2 ...

  3. JAVA实现单例模式的四种方法和一些特点

    JAVA实现单例模式的四种方法和一些特点,需要的朋友可以参考一下     一.饿汉式单例类 复制代码 代码如下: public class Singleton  {      private Sing ...

  4. Java中创建对象的几种方式

    Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Cl ...

  5. java中线程分两种,守护线程和用户线程。

    java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...

  6. java中需要关注的3大方面内容/Java中创建对象的几种方法:

    1)垃圾回收 2)内存管理 3)性能优化 Java中创建对象的几种方法: 1)使用new关键字,创建相应的对象 2)通过Class下面的new Instance创建相应的对象 3)使用I/O流读取相应 ...

  7. Java中BigDecimal的8种舍入模式是怎样的

    Java中BigDecimal的8种舍入模式是怎样的?下面长沙欧柏泰克软件学院和大家一起来学习下吧:  java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecima ...

  8. Java中常见的5种WEB服务器介绍

    这篇文章主要介绍了Java中常见的5种WEB服务器介绍,它们分别是Tomcat.Resin.JBoss.WebSphere.WebLogic,需要的朋友可以参考下 Web服务器是运行及发布Web应用的 ...

  9. java中 this 的三种用法

    Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...

随机推荐

  1. Service Fabric service 根据环境变量读取配置文件

    前言 一个服务或者产品,往往需要三个环境:一个开发环境(Development),一个测试环境(Staging),一个生产环境(Production), 这就不可避免的需要多个配置文件来匹配相应的环境 ...

  2. vue + element + 初始化项目

    前提:已经安装了好了npm 和 vue脚手架 注意: 进入想要放置项目的目录下. 1.vue init webpack sun-vue-element 2.根据提示输入 y/n 3.npm run d ...

  3. 关于微信JS-SDK 分享接口的两个报错记录

    一.前提: 微信测试号,用微信开发者工具测试 二.简单复述文档: 1.引入JS文件 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/j ...

  4. (一)初识Redis

    1.redis简介 Redis是一个速度非常快的key-value非关系型存储数据库,可以存储5种形态的键值对,可以将存储在内存中的键值对持久化到硬盘,可以使用复制特性扩展读性能,还可以使用客户端分片 ...

  5. python从学渣到学沫的半月天

    今天又要引进一个新的知识点了,就是模块,可以直接引用的一个东西,从实用性来说很强大,不过还是需要记住模块的类型啊,如何应用还是需要学习和了解的.其中模块是分三种的,一种内置模块python内部提供的功 ...

  6. Luogu P5279 [ZJOI2019]麻将

    ZJOI2019神题,间接送我退役的神题233 考场上由于T2写挂去写爆搜的时候已经没多少时间了,所以就写挂了233 这里不多废话直接开始讲正解吧,我们把算法分成两部分 1.建一个"胡牌自动 ...

  7. 解决ASP.NET Core MVC调试慢的问题

    最近在做的一个项目中,发现网页端同时发起了4个AJAX请求需要数秒才获取到响应,太慢了,当我把请求数降低为1个的时候,速度看起来就比较正常,增加到2个同时的请求后,速度就有些慢了,3个的话就明显慢了, ...

  8. Java数据结构和算法 - OverView

    Q: 为什么要学习数据结构与算法? A: 如果说Java语言是自动档轿车,C语言就是手动档吉普.数据结构呢?是变速箱的工作原理.你完全可以不知道变速箱怎样工作,就把自动档的车子从1档开到4档,而且未必 ...

  9. 使用ASP.NET Core支持GraphQL -- 较为原始的方法

    GraphQL简介 下面是GraphQL的定义: GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述 ...

  10. EF实体实现链接字符串加密

    1.加密解密方法 using System;using System.Security.Cryptography; using System.Text;namespace DBUtility{ /// ...