Java单例的写法详解

目录
  • 饿汉式
  • 懒汉式一
  • 懒汉式二
  • 懒汉式三(双重检查)
  • 静态内部类
  • 枚举
  • 总结

单例模式,顾名思义,就是全局只保存有一个实例并且能够避免用户去手动实例化,所以单例模式的各种写法都有一个共同点,不能通过new关键字去创建对象,因此,如果能够通过构造方法实例化,那么就一定要将其声明为私有。

饿汉式

public class PersonResource {
    public static final PersonResource PERSON_RESOURCE_SINGLETON = new PersonResource();
    private PersonResource(){}
    public  static PersonResource getInstance() {
        return PERSON_RESOURCE_SINGLETON;
    }
}

这种方式可以说是最安全,也最简单的了,但却有一个缺点,那就是无论这个实例有没有被使用到,都会被实例化,颇有些浪费资源

懒汉式一

既然前一种方法有些浪费资源,那就换一种写法,让类在被调用的时候实例化

public class PersonResource {
    private static PersonResource personResourceSingleton;
    private PersonResource() {
    }
    public static PersonResource getPersonResourceSingleton(){
        if(null==personResourceSingleton){
            personResourceSingleton = new PersonResource();
        }
        return personResourceSingleton;
    }
}

这种方式能够在需要用到该实例的时候再初始化,也能够在单线程下很好的运行,但如果是多线程就容易出现问题了。

懒汉式二

public class PersonResource {
    private static PersonResource personResourceSingleton;
    private PersonResource() {
    }
    public static PersonResource getPersonResourceSingleton(){
        if(null==personResourceSingleton){
            personResourceSingleton = new PersonResource();
        }
        return personResourceSingleton;
    }
}

多线程之所以会出现问题,是因为多个线程能够并发执行getPersonResourceSingleton方法,从而导致在判断是否为空时出现问题。

既然如此,加上锁 ,使其互斥即可。这里又出现了一个问题,每次获取实例的时候都需要加锁解锁,而当一个实例已经被产生后,再加锁就有些多余了;

懒汉式三(双重检查)

public class PersonResource {
    private PersonResource(){    }
    private volatile static PersonResource personResource;
    public  static PersonResource getInstance(){
        if(personResource==null){
            synchronized (PersonResource.class){
                if(personResource==null){
                    personResource = new PersonResource();
                }
            }
        }
        return personResource;
    }
}

既然实例确定产生后不再需要加锁,那我们在获取锁前先判断一次是否已经有实例存在就可以解决问题了

静态内部类

public class PersonResource {
    private PersonResource(){}
    private static class PersonResourceHolder{
        public static PersonResource personResourceSingleton = new PersonResource();
    }
    public static PersonResource getInstance(){
        return PersonResourceHolder.personResourceSingleton;
    }
}

除了双重检查能够保证安全的单例外,用一个静态内部类去持有单例也是可以的,静态内部类保证了不会随外部类的加载而加载,这保证了延迟加载,同时在加载该类的时候就实例化单例,保证了线程安全;

枚举

public enum PersonResource {
    /**
     * PersonResource单例
     */
    personResource;
    public void setPersonResource(){
    }
}

以上几种方式基本就够用了,但都有一个共同的缺点,面对序列化和反序列化,是无法保证单例的,但枚举的特性却能保证这一点

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 详解java中的6种单例写法及优缺点

    在java中,单例有很多种写法,面试时,手写代码环节,除了写算法题,有时候也会让手写单例模式,这里记录一下单例的几种写法和优缺点. 1.初级写法 2.加锁 3.饿汉式 4.懒汉式 5.双锁检验 6.内部类 1.初级写法 package com.java4all.test6; /** * Author: yunqing * Date: 2018/8/13 * Description:单例模式 -- 初级 */ public class Singleton { private static Sing

  • 浅谈java 单例模式DCL的缺陷及单例的正确写法

    1 前言 单例模式是我们经常使用的一种模式,一般来说很多资料都建议我们写成如下的模式: /** * Created by qiyei2015 on 2017/5/13. */ public class Instance { private String str = ""; private int a = 0; private static Instance ins = null; /** * 构造方法私有化 */ private Instance(){ str = "hell

  • Java中单例模式的7种写法

    第一种(懒汉,线程不安全): public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } 这种写法lazy loading很明显,但是致命的是在多线程不能正常工作.

  • Java版的7种单例模式写法示例

    前言 今天看到某一篇文章的一句话 单例DCL 前面加 V .就这句话让我把 单例模式 又仔细看了一遍. Java 中的 单例模式 是我们一直且经常使用的设计模式之一,大家都很熟悉,所以这篇文章仅仅做我自己记忆. 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 单例模式 涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方式,可以直接访问,

  • Java单例模式的8种写法(推荐)

    单例:Singleton,是指仅仅被实例化一次的类. 饿汉单例设计模式 一.饿汉设计模式 public class SingletonHungry { private final static SingletonHungry INSTANCE = new SingletonHungry(); private SingletonHungry() { } public static SingletonHungry getInstance() { return INSTANCE; } } 因为单例对象

  • Java单例的写法详解

    目录 饿汉式 懒汉式一 懒汉式二 懒汉式三(双重检查) 静态内部类 枚举 总结 单例模式,顾名思义,就是全局只保存有一个实例并且能够避免用户去手动实例化,所以单例模式的各种写法都有一个共同点,不能通过new关键字去创建对象,因此,如果能够通过构造方法实例化,那么就一定要将其声明为私有. 饿汉式 public class PersonResource { public static final PersonResource PERSON_RESOURCE_SINGLETON = new Perso

  • java 设计模式之单例的实例详解

    java 设计模式之单例的实例详解 设计模式思想 什么是设计模式:我作为初学者,今天第一次正式学习设计模式,我觉得对与理解什么是设计模式很重要,那么什么是设计模式呢? 设计模式:解决问题的一种行之有效的思想. 设计模式:用于解决特定环境下.重复出现的特定问题的解决方案 我的理解是前人在软件设计的时候碰到了一类问题,他们总结出了一套行之有效,并且经过验证的解决方案. 设计模式的优点: 1.设计模式都是一些相对优秀的解决方案,很多问题都是典型的.有代表性的问题,学习设计模式,我们就不用自己从头来解决

  • JAVA 静态的单例的实例详解

    JAVA  静态的单例的实例详解 实现代码: public class Printer { private Printer(){ } public static Printer newInstance(){ return CreatePrinter.mPrinter; } private static class CreatePrinter{ private final static Printer mPrinter = new Printer(); } } 因为静态的单例对象没有作为类的成员变

  • Java之单例设计模式示例详解

    单例设计模式 保证一个类在内存中只能有一个对象. 思路: 1)如果其他程序能够随意用 new 创建该类对象,那么就无法控制个数.因此,不让其他程序用 new 创建该类的对象. 2)既然不让其他程序 new 该类对象,那么该类在自己内部就要创建一个对象,否则该类就永远无法创建对象了. 3)该类将创建的对象对外(整个系统)提供,让其他程序获取并使用. 饿汉式: 一上来我就把对象给你 new 好了,你来了直接就可以拿去"吃"了 懒汉式 (要是有人问单例的延迟加载方式指的就是这种方式) 一开始

  • JAVA  静态的单例的实例详解

    JAVA  静态的单例的实例详解 实现代码: public class Printer { private Printer(){ } public static Printer newInstance(){ return CreatePrinter.mPrinter; } private static class CreatePrinter{ private final static Printer mPrinter = new Printer(); } } 因为静态的单例对象没有作为类的成员变

  • C++单例类模板详解

    单例类 描述 指在整个系统生命期中,一个类最多只能有一个实例(instance)存在,使得该实例的唯一性(实例是指一个对象指针)  , 比如:统计在线人数 在单例类里,又分为了懒汉式和饿汉式,它们的区别在于创建实例的时间不同: 懒汉式 : 指代码运行后,实例并不存在,只有当需要时,才去创建实例(适用于单线程) 饿汉式 : 指代码一运行,实例已经存在,当时需要时,直接去调用即可(适用于多线程) 用法 将构造函数的访问属性设置为private, 提供一个GetInstance()静态成员函数,只能供

  • Java多例设计模式实例详解

    本文实例讲述了Java多例设计模式.分享给大家供大家参考,具体如下: 一.多例设计模式定义 多例设计模式就是存在多个对象实例,供外部应用裯用,比喻数据库连接池. 二.多例模式静态类图 三.多例模式代码实现 1. 多例模式核心类 package com.demo.multipleton; import java.util.ArrayList; /** * 多例模式 * * @author * */ public class Multipleton { // 多例数量 private static

  • Java之单例模式实现方案详解

    单例模式是最常用到的设计模式之一,熟悉设计模式的朋友对单例模式都不会陌生.一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式.但是除了这两种方式,本文还会介绍其他几种实现单例的方式,让我们来一起看看吧. 简介 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在. 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象

  • Java 8 lambda表达式引入详解及实例

    Java 8 lambda表达式引入详解及实例 eclipse 下载安装 Help -> EclipseMarketplace -> 搜索Java 8 Kepler ->Java 8 support for eclipse Kepler SR2 安装完成后需要重启 Android Studio 在project的build.gradle文件中添加 buildscript { dependencies { classpath 'me.tatarka:gradle-retrolambda:3

  • Java基础之代码死循环详解

    一.前言 代码死循环这个话题,个人觉得还是挺有趣的.因为只要是开发人员,必定会踩过这个坑.如果真的没踩过,只能说明你代码写少了,或者是真正的大神. 尽管很多时候,我们在极力避免这类问题的发生,但很多时候,死循环却悄咪咪的来了,坑你于无形之中.我敢保证,如果你读完这篇文章,一定会对代码死循环有一些新的认识,学到一些非常实用的经验,少走一些弯路. 二.死循环的危害 我们先来一起了解一下,代码死循环到底有哪些危害? 程序进入假死状态, 当某个请求导致的死循环,该请求将会在很大的一段时间内,都无法获取接

随机推荐