`

Java单例模式

    博客分类:
  • java
 
阅读更多
Singleton 模式的宗旨在于确保某个类只有一个实例,别且为之提供一个全局访问点。为了防止其他工作人员实例化我们的类,

可以为该类创建唯一一个构造器,并将构造器的可见设置为私有。值得注意的是,如果我们创建了其他的非私有的构造器,或者根本没有为该类提

供构造器,那么其他人员还是能实例化我们的类。 如果不希望提前创建单例对象,我们可以等到第一次使用该单例对象的时候在创建它,即

滞后初始化。滞后初始化单例对象有两个理由:

1.也许在静态初始化时间,你没有关于如何初始化单例对象的足够信息。

2.选择滞后初始化单例的目的也许为了等待资源,诸如数据库连接,尤其是在某些特定会话中不需要这个单例的应用程序中。

如果在多线程环境中对单例采用滞后初始化,那么我们必须小心防止多个线程同时初始化该

通常单例模式在Java语言中,有两种构建方式:

懒汉方式:指全局的单例实例在第一次被使用时构建。延迟初始化。

饿汉方式:指全局的单例实例在类装载时构建。 急切初始化。

1,饿汉式单例类

    public class Singleton1 { 
         
        private Singleton1() { 
        } 
        // 在自己内部定义自己一个实例. 
        // 注意这是private 只供内部调用 
    
        private static Singleton1 instance = new Singleton1(); 
    
        /** *//** 
         *  这里提供了一个供外部访问本class的静态方法,可以直接访问 
         * @return 
         */
        public static Singleton1 getInstance() { 
            return instance; 
        } 
    }


懒汉式单例类

    public class Singleton2 { 
    
        private static Singleton2 instance = null; 
        /** *//** 
         * 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次  
         * 使用时生成实例,提高了效率! 
         * @return 
         */
        public static  Singleton2 getInstance() {     
            if (instance == null) 
                instance = new Singleton2(); 
            return instance; 
        } 
    }

下面主要多线程问题,在懒汉单例中,单线程是没有问题的,但多线程时就会有可能出现两个或者以上的Singletion2实例的情况。

例如:线程1在判断instance==null为真,扫行new操作时,在执行new操作之前,判断为真之后,线程2正好执行判断操作,这时instance还为null.因此,线程2也会执行new操作。以此类推,在高并发下面,就可能存在两个或者以上的Singletion2的实例。显然,这是不正确的。

因此改变代码如下:

    public class Singleton3 { 
    
        private static Singleton3 instance = null; 
        /** *//** 
         * 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次  
         * 使用时生成实例,提高了效率! 
         * 为了多线程不出错,加入了同步标志 
         * @return 
         */
        public static synchronized  Singleton3 getInstance() {     
            if (instance == null) 
                instance = new Singleton3(); 
            return instance; 
        } 
    
    }

但这样又产生了一个问题,每次获取实例时方法都是同步的,显然性能很受影响的,所以继续更改代码如下:

先记一下:volatile(网上抄的)

volatile, 用更低的代价替代同步

为什么使用volatile比同步代价更低?

同步的代价, 主要由其覆盖范围决定, 如果可以降低同步的覆盖范围, 则可以大幅提升程序性能.

而volatile的覆盖范围仅仅变量级别的. 因此它的同步代价很低.

volatile原理是什么?

volatile的语义, 其实是告诉处理器, 不要将我放入工作内存, 请直接在主存操作我.(工作内存详见java内存模型)

因此, 当多核或多线程在访问该变量时, 都将直接操作主存, 这从本质上, 做到了变量共享.

volatile的有什么优势?

1, 更大的程序吞吐量

2, 更少的代码实现多线程

3, 程序的伸缩性较好

4, 比较好理解, 无需太高的学习成本

volatile有什么劣势?

1, 容易出问题

2, 比较难设计

volatile使用jdk要求1.5版本及1.5以上。

改进后的代码如下(又叫双重加锁):

    public class Singleton4 { 
       private static volatile Singleton4 instance; 
        /** *//** 
         * 双重加锁实现多线程运用和性能优化 
         * @return 
         */
        public static Singleton4 getInstance() 
        { 
          if (instance == null) 
          { 
            synchronized(Singleton4.class) {  //1 
              if (instance == null)          //2 
                instance = new Singleton4();  //3 
            } 
          } 
          return instance; 
        } 
    } 
分享到:
评论

相关推荐

    Java 单例模式.pptx

    ### Java 单例模式详解 #### 一、什么是单例模式? 单例模式是一种常用的软件设计模式,在这种模式中,一个类只能拥有一个实例,并且该类必须自行创建并提供这个实例。通常,单例模式用于确保某个类在整个应用程序...

    java单例模式实例

    在Java中,有多种实现单例模式的方法,每种都有其特点和适用场景。接下来,我们将深入探讨这些实现方式。 首先,我们来看**懒汉式(Lazy Initialization)**。这种实现方式是在类被首次请求时才创建单例对象,延迟...

    使用Java单例模式实现一个简单的日志记录器.txt

    ### 使用Java单例模式实现一个简单的日志记录器 #### 一、单例模式简介 单例模式是一种常用的软件设计模式,在该模式中,一个类只能创建一个实例,并且提供了一个全局访问点来访问该实例。单例模式的主要优点包括...

    Java 单例模式 懒汉模式

    Java 单例模式 懒汉模式 //懒汉式 多线程中不可以保证是一个对象

    Java 单例模式 工具类

    Java中的单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供全局访问点。在Java编程中,单例模式常用于控制资源的访问,比如数据库连接池、线程池或者日志对象等。本篇文章将深入探讨如何在Java中...

    JAVA单例模式的几种实现方法

    ### JAVA单例模式的几种实现方法 #### 一、饿汉式单例类 饿汉式单例类是在类初始化时就已经完成了实例化的操作。这种实现方式简单且线程安全,因为实例化过程是在编译期间完成的,不会受到多线程的影响。 **代码...

    Java单例模式设计

    Java单例模式是一种常用的设计模式,它保证一个类只有一个实例,并提供全局访问点。这种模式在需要频繁创建和销毁对象的场景中,或者当对象昂贵时(如数据库连接),能够节省系统资源,提高效率。本篇文章将深入探讨...

    java单例模式及实现

    Java单例模式及实现 Java单例模式是一种常见的设计模式,确保某一个类只有一个实例,而且向这个系统提供这个实例。单例模式可以分为三种:懒汉式单例、饿汉式单例、登记式单例。 单例模式的要点 1. 某个类只能有...

    Java单例模式深入理解

    Java单例模式是一种设计模式,它允许在程序中创建唯一一个类实例,通常用于管理共享资源,例如数据库连接、线程池或者配置对象等。单例模式的核心在于限制类的构造函数,确保类只能被初始化一次,从而实现全局唯一的...

    Java单例模式应用研究.pdf

    ### Java单例模式应用研究 #### 一、单例模式概述 单例模式(Singleton Pattern)作为一种最基本的创建型设计模式,其主要目的是控制一个类的实例化过程,确保在整个应用程序中仅存在一个实例,并且该实例能够被全局...

    java单例模式的例子

    Java单例模式是一种常见的设计模式,它在软件工程中用于控制类的实例化过程,确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统资源管理、缓存、日志记录等方面应用广泛。下面我们将深入探讨Java单例...

    java单例模式连接数据库源码

    Java单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在数据库连接管理中,使用单例模式能有效控制资源,避免频繁创建和关闭数据库连接导致的性能损失和资源浪费。以下是对Java单例模式...

    java单例模式代码实例

    Java单例模式是一种常用的设计模式,它用于保证一个类只有一个实例,并提供全局访问点。这种模式在系统资源有限或者需要共享昂贵对象时尤其有用,比如数据库连接池、线程池等。下面我们将深入探讨Java单例模式的实现...

    java 单例模式(懒汉式与饿汉式).docx

    java 单例模式(懒汉式与饿汉式) java 单例模式是一种常用的软件设计模式。在它的可信结构中只包含一个被实例化单例的特别类。通过单例设计模式可以把整系统中的一个类只有一个实例。单例设计模式又分为两种方式,...

    Java单例模式.pdf

    Java单例模式是设计模式中的一种,在软件开发中扮演着重要的角色。单例模式的目的是保证一个类仅有一个实例,并且提供一个全局访问点。在Java中实现单例模式有多种方法,主要包括懒汉式、饿汉式、注册式(使用容器)...

Global site tag (gtag.js) - Google Analytics