`

Java 单例模式详解(转)

    博客分类:
  • java
阅读更多
概念:
  java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
  单例模式有一下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。
  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

首先看一个经典的单例实现。

public class Singleton {
    private static Singleton uniqueInstance = null;

    private Singleton() {
       // Exists only to defeat instantiation.
    }

    public static Singleton getInstance() {
       if (uniqueInstance == null) {
           uniqueInstance = new Singleton();
       }
       return uniqueInstance;
    }
    // Other methods...
}
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)

但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。


1 public class TestStream {
2     private String name;
3     public String getName() {
4         return name;
5     }
6     public void setName(String name) {
7         this.name = name;
8     }
9     //该类只能有一个实例
10     private TestStream(){}    //私有无参构造方法
11     //该类必须自行创建
12     //有2种方式
13     /*private static final TestStream ts=new TestStream();*/
14     private static TestStream ts1=null;
15     //这个类必须自动向整个系统提供这个实例对象
16     public static TestStream getTest(){
17         if(ts1==null){
18             ts1=new TestStream();
19         }
20         return ts1;
21     }
22     public void getInfo(){
23         System.out.println("output message "+name);
24     }
25 }


1 public class TestMain {
2     public static void main(String [] args){
3         TestStream s=TestStream.getTest();
4         s.setName("张孝祥");
5         System.out.println(s.getName());
6         TestStream s1=TestStream.getTest();
7         s1.setName("张孝祥");
8         System.out.println(s1.getName());
9         s.getInfo();
10         s1.getInfo();
11         if(s==s1){
12             System.out.println("创建的是同一个实例");
13         }else if(s!=s1){
14             System.out.println("创建的不是同一个实例");
15         }else{
16             System.out.println("application error");
17         }
18     }
19 }

运行结果:
  张孝祥
  张孝祥
  output message 张孝祥
  output message 张孝祥
  创建的是同一个实例

结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。

1.饿汉式单例类


1 //饿汉式单例类.在类初始化时,已经自行实例化
(特性:1. 每次装载都需要消耗内存空间  
       2.以空间换取时间的
       3.线程是安全的
)

2 public class Singleton1 {
3     //私有的默认构造子
4     private Singleton1() {}
5     //已经自行实例化
6     private static final Singleton1 single = new Singleton1();
7     //静态工厂方法
8     public static Singleton1 getInstance() {
9         return single;
10     }
11 }

2.懒汉式单例类


1 //懒汉式单例类.在第一次调用的时候实例化
(特性:1.第一次装载都需要消耗内存空间 后面不需要实例化类  
       2. 以时间换空间的设计
      3 在多线程的时候会产生多个实例,这样就不安全的)

2 public class Singleton2 {
3     //私有的默认构造子
4     private Singleton2() {}
5     //注意,这里没有final   
6     private static Singleton2 single=null;
7     //静态工厂方法
8     public synchronized  static Singleton2 getInstance() {
9          if (single == null) { 
10              single = new Singleton2();
11          } 
12         return single;
13     }
14 }

3.登记式单例类


1 import java.util.HashMap;
2 import java.util.Map;
3 //登记式单例类.
4 //类似Spring里面的方法,将类名注册,下次从里面直接获取。
5 public class Singleton3 {
6     private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
7     static{
8         Singleton3 single = new Singleton3();
9         map.put(single.getClass().getName(), single);
10     }
11     //保护的默认构造子
12     protected Singleton3(){}
13     //静态工厂方法,返还此类惟一的实例
14     public static Singleton3 getInstance(String name) {
15         if(name == null) {
16             name = Singleton3.class.getName();
17             System.out.println("name == null"+"--->name="+name);
18         }
19         if(map.get(name) == null) {
20             try {
21                 map.put(name, (Singleton3) Class.forName(name).newInstance());
22             } catch (InstantiationException e) {
23                 e.printStackTrace();
24             } catch (IllegalAccessException e) {
25                 e.printStackTrace();
26             } catch (ClassNotFoundException e) {
27                 e.printStackTrace();
28             }
29         }
30         return map.get(name);
31     }
32     //一个示意性的商业方法
33     public String about() {   
34         return "Hello, I am RegSingleton.";   
35     }   
36     public static void main(String[] args) {
37         Singleton3 single3 = Singleton3.getInstance(null);
38         System.out.println(single3.about());
39     }
40 }
  • 大小: 80 KB
分享到:
评论

相关推荐

    单例模式详解~~单例模式详解~~

    在Java中,实现单例模式有多种方式,但最常见的问题是线程安全问题。例如,上述代码展示了一个简单的单例实现,称为"饿汉式"单例,因为无论是否需要,它都会在类加载时立即创建实例。这种方式虽然简单,但在多线程...

    Java 单例模式.pptx

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

    java单例模式详解

    Java单例模式是一种常见的设计模式,它用于控制类的实例化过程,确保一个类在整个应用程序中只有一个实例存在。这种模式通常用于管理共享资源或者需要频繁创建和销毁的对象,以节省系统资源并提供全局访问点。 单例...

    Java设计模式-单例模式详解

    Java设计模式-单例模式详解 单例模式是 Java 设计模式中的一种常用的设计模式,旨在保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式的目的是为了保证在一个进程中,某个类有且仅有一个实例。 ...

    java单例模式详解Java系列2021.pdf

    Java语言中的单例模式实现有多种方式,包括饿汉式、懒汉式和登记式单例。不同的实现方式适应不同的场景和需求,各有优劣。 首先,饿汉式单例是类加载时就会立即初始化,它的好处是实现简单,且在多线程环境下能保证...

    java设计模式之单例模式详解

    Java设计模式之单例模式详解 一、单例模式概览 单例模式(Singleton Pattern)是面向对象设计模式中的一种,属于创建型模式。它确保一个类仅有一个实例,并提供一个全局访问点来访问该实例。单例模式的核心在于控制...

    java 多线程单例模式详解

    ### Java多线程单例模式详解 #### 一、单例模式概述 单例模式(Singleton Pattern)是一种常用的软件设计模式,它确保一个类仅有一个实例,并提供一个全局访问点。这种模式通常用于那些需要频繁实例化然后销毁的...

    9种Java单例模式详解(推荐)

    Java单例模式详解 Java单例模式是Java编程中的一种设计模式,旨在保证一个类仅有一个实例,并提供一个全局访问点。下面我们将对9种Java单例模式进行详细的介绍。 首先,单例模式的特点是: 1. 一个类只允许产生...

    单例模式详解

    单例模式详解 单例模式是 Java 设计模式中的一种常见模式,旨在保证整个应用中只有一个类的实例存在。单例模式分为三种:懒汉式单例、饿汉式单例、登记式单例。下面对单例模式的特点、实现方式和应用场景进行详细...

    Java双重检查加锁单例模式的详解

    "Java双重检查加锁单例模式的详解" Java双重检查加锁单例模式是一种常用的单例模式实现方法,但是在多线程环境下,它存在一些问题。在这篇文章中,我们将探讨Java双重检查加锁单例模式的详解,包括它的优点和缺点,...

    设计模式之单例模式详解.pdf

    设计模式之单例模式详解 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。 单例模式的实现主要是...

    JAVA单例模式的登录案例

    根据给定的信息,我们可以深入探讨Java单例模式的登录案例,并从中提炼出多个重要的知识点。 ### 单例模式概述 单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式通常...

    详解JAVA单例模式及多种实现.doc

    以下是几种常见的Java单例模式实现方式: 1. **饿汉式(静态常量)**: 这种方式在类加载时即初始化实例,线程安全,但可能导致不必要的内存占用。 ```java public class Singleton1 { private Singleton1() {} ...

    java 单例模式的实例详解

    java 单例模式的实例详解 java 单例模式是指一种设计模式,确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在java中,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例。单例模式有以下特点...

    Java 单例模式线程安全问题

    Java 单例模式线程安全问题详解 Java 单例模式线程安全问题是指在 Java 中实现单例模式时,如何确保线程安全的问题。单例模式是指在整个应用程序生命周期中,只有一个实例存在的设计模式。这种模式可以提高性能,...

    java 单例模式和工厂模式实例详解.docx

    在这个文档中,我们主要关注两种设计模式:单例模式和工厂模式。 **单例模式** 是用来保证一个类只有一个实例,并提供一个全局访问点。这种模式在Java中广泛使用,比如控制数据库连接、线程池等资源管理。单例模式...

    【课堂笔记】单例模式详解

    单例模式是软件设计模式中的一种经典模式,它在Java编程中被广泛使用。这个模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于可以控制资源的共享,减少内存开销,以及简化对全局配置...

    java 设计模式详解

    Java设计模式详解涵盖了在Java编程中广泛使用的一些经典设计模式。这些模式不仅有助于提高代码的可读性、可维护性和可扩展性,还能促进团队之间的沟通与协作。下面,我们将深入探讨几个重要的Java设计模式。 1. ...

Global site tag (gtag.js) - Google Analytics