Java设计模式04-单例模式

定义

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

通俗点讲单例模式就是保证只new 了一个对象每次获取都是这一个对象的模式。

最简单的单例实现

public class Singleton {
    //使用一个私有的类成员保存唯一的实例对象。
    private static Singleton uniqueInstance;
    //私有化构造方法,保证不能从外部实例化。
    private Singleton() {

    }
    //提供一个公有的静态方法获取到唯一的实例。
    public static Singleton getInstance() {
        //判断唯一实例是否被实例化了
        if(uniqueInstance==null)
            //未实例化则实例化
            uniqueInstance = new Singleton();
        //返回唯一实例。
        return uniqueInstance;
    }
}

但是这种方式在多线程的情况下不能保证只有一个实例,因为在判断对象为空时可能有多个线程通过并实例化对象。如下

public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        for(int i = 1 ; i < 100 ;i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Singleton instance = Singleton.getInstance();
                    System.out.println(instance.hashCode());
                }}).start();
        }
    }
}

输出

350646954

2006299335

2006299335

2006299335

350646954

2006299335

2006299335

2006299335

2006299335

2006299335

2006299335

***

更加安全的单例模式

//双重监测加锁单例
public class DoubleCheckSingleton {
    //静态变量保存唯一实例,使用volatile关键字保证线程可见性。
    private static volatile DoubleCheckSingleton uniqueInstance;
    //私有化构造函数
    private DoubleCheckSingleton() {}
    //获取实例的方法
    public static DoubleCheckSingleton getInstance() {
        //判断唯一实例是否实例化,避免不必要的加锁带来的性能问题。
        if(uniqueInstance==null) {
            //加锁保证判断和实例化操作的原子性
            synchronized(DoubleCheckSingleton.class) {
                //再次判断是否为空,因为可能多个线程通过上面的第一次检测。
                if(uniqueInstance==null)
                    uniqueInstance = new DoubleCheckSingleton();
            }
        }
        return uniqueInstance;
    }
}

//饿汉模式单例
public class EagerSingleton {
    //静态变量保存唯一实例,保证在类加载时实例化一次。
    private static EagerSingleton uniqueInstance = new EagerSingleton();
    //私有化构造函数
    private EagerSingleton() {

    }
    //获取实例方法
    public static EagerSingleton getInstance() {
        return uniqueInstance;
    }
}

//静态内部类单例
public class StaticInnerClassSingleton {
    //私有化构造函数
    private StaticInnerClassSingleton() {}
    //定义一个静态内部类,在该类被加载时实例化一个唯一的实例并保存在变量中。
    static class InstanceHolder{
        private  static StaticInnerClassSingleton uniqueInstance = new StaticInnerClassSingleton();
    }
    //获取唯一实例
    public StaticInnerClassSingleton getInstance() {
        return InstanceHolder.uniqueInstance;
    }
}

恶汉模式和静态内部类模式的区别在于是否在类加载时就实例化对象。为了验证我们在它们的构造方法中打印一句话。

private EagerSingleton() {
    System.out.println("EagerSingleton init");
}

private StaticInnerClassSingleton() {
    System.out.println("StaticInnerClassSingleton init");
}

测试

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        // TODO Auto-generated method stub
        Class.forName("singleton.EagerSingleton");
        Class.forName("singleton.StaticInnerClassSingleton");
    }
}

结果

EagerSingleton init

总结

单例模式是一个很实用的模式,虽然只需要一个类就可以实现该模式,但是我们需要注意在多线程环境下它的安全性。

源代码:https://github.com/Panici4/DesignPattern/tree/master/singleton

原文地址:https://www.cnblogs.com/panici12/p/9537550.html

时间: 2024-10-17 07:57:21

Java设计模式04-单例模式的相关文章

(九)JAVA设计模式之单例模式

JAVA设计模式之单例模式 一.单例模式的介绍 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点.     全局对象和Singleton模式有本质的区别,因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本不支持全局变量.最重要的是传统的全局对象并不能阻止一个类被实例化多次. 二.单例模式的特点 单例类只能有一个实例 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例.

java 设计模式之单例模式

--------2015-11-20 14:45:10 java设计模式之单例模式(Singleton): ---应用场合:只需要一个对象就可以了,例如一个朝代一个皇帝. ---作用:保证某个应用程序中某个实例有且只有一个.共同使用一个,节省资源. ---类型:饿汉模式,懒汉模式. 一.饿汉模式(类加载的时候就会实例化,线程安全) 1 package com.sun.singleton; 2 3 //饿汉模式 4 public class Singleton { 5 6 //将构造函数私有化,不

java设计模式之单例模式(Singleton)

Java设计模式之单例模式 单例模式是什么? 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式如何来设计呢? 保证一个类只能有一个实例,那么我们不能无限制的new 来创建,因为我们知道,new一次就是一个新的对象,那么构造器只能私有化private -- 构造器私有化 构造器私有化了,问题又出现了,构造器私有化了,那么我们怎么来创建唯一的对象呢?-- 提供一个公有的方法/提供一个公有的静态属性 再分析一下,公有方法, 实例方法还是类方法呢?--公有的类方法(获取类实例) 依据以上

java设计模式之单例模式(Singleton pattern)

java设计模式之单例模式(Singleton pattern) 单例模式的定义: Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the i

Java设计模式之单例模式(七种写法)

Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleton instance; private Singleton (){}//私有化构造方法,防止类被实例化 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } retu

折腾Java设计模式之单例模式

博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access to it. 一个类仅仅只有一个实例,并且提供全局的接入点.简洁点理解就是涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问它自己唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 饿汉式单例模式 public final class EagerSi

Java设计模式:单例模式

概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,但只能

[转]JAVA设计模式之单例模式

原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话

Java 设计模式(3)单例模式

前言 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,

JAVA设计模式之单例模式(转)

本文继续介绍23种设计模式系列之单例模式. 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器