单例 (JAVA)

 java中单例模式是一种常见的设计模式,以下是它的特点:


  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例

第一种(懒汉,线程不安全):

1 public class Singleton {  
 2     private static Singleton instance;  
 3

private Singleton (){}   
 4     public static Singleton getInstance() {  
 5     if (instance == null) {  
 6         instance = new Singleton();  
 7     }  
 8     return instance;  
 9     }  
10 }  
11

 懒汉式是典型的时间换空间,就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间

 由于懒汉式的实现是线程安全的,这样会降低整个访问的速度,而且每次都要判断.

第二种(懒汉,线程安全):

1 public class Singleton {  
 2     private static Singleton instance;  
 3

private Singleton (){}
 4     public static synchronized Singleton getInstance() {  
 5     if (instance == null) {  
 6         instance = new Singleton();  
 7     }  
 8     return instance;  
 9     }  
10 }  
11

第三种(饿汉):

1 public class Singleton {  
2     private static Singleton instance = new Singleton();  
3

private Singleton (){}
4     public static Singleton getInstance() {  
5     return instance;  
6     }  
7 }  
8

第四种(饿汉,变种):

1 public class Singleton {  
 2     private Singleton instance = null;  
 3     static {  
 4     instance = new Singleton();  
 5     }  
 6

private Singleton (){}
 7     public static Singleton getInstance() {  
 8     return this.instance;  
 9     }  
10 }  
11

表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始化即实例化instance。

第五种(静态内部类):

1 public class Singleton {  
 2     private static class SingletonHolder {  
 3     private static final Singleton INSTANCE = new Singleton();  
 4     }  
 5

private Singleton (){}
 6     public static final Singleton getInstance() {  
 7         return SingletonHolder.INSTANCE;  
 8     }  
 9 }  
10

优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading

第六种(枚举):

1 public enum Singleton {  
2     INSTANCE;  
3     public void whateverMethod() {  
4     }  
5 }  
6

优点:不仅能避免多线程同步问题,而且还能防止反序列化

第七种(双重校验锁):

1 public class Singleton {  
 2     private volatile static Singleton singleton;  
 3

private Singleton (){}   
 4     public static Singleton getSingleton() {  
 5     if (singleton == null) {  
 6         synchronized (Singleton.class) {  
 7         if (singleton == null) {  
 8             singleton = new Singleton();  
 9         }  
10         }  
11     }  
12     return singleton;  
13     }  
14 }  
15

总结

有两个问题需要注意:

1、如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些

servlet容器对每个

servlet使用完全不同的类  装载器,这样的话如果有两个

servlet访问一个单例类,它们就都会有各自的实例。

2、如果

Singleton实现了

java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。

对第一个问题修复的办法是:

1 private static Class getClass(String classname)      
 2                                          throws ClassNotFoundException {     
 3       ClassLoader classLoader = Thread.currentThread().getContextClassLoader();     
 4       
 5       if(classLoader == null)     
 6          classLoader = Singleton.class.getClassLoader();     
 7       
 8       return (classLoader.loadClass(classname));     
 9    }     
10 }  
11

对第二个问题修复的办法是:

1 public class Singleton implements java.io.Serializable {     
 2    public static Singleton INSTANCE = new Singleton();     
 3       
 4    protected Singleton() {     
 5         
 6    }     
 7    private Object readResolve() {     
 8             return INSTANCE;     
 9       }    
10 }   
11

时间: 2024-10-22 15:38:42

单例 (JAVA)的相关文章

java单例类/

java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一但有了初始值,就不能被重新赋值 static修饰的成员变量可以在静态代码块中 或申明该成员时指定初始值 实例成员可以在非静态代码块中,申明属性,或构造器中指定初始值 final修饰的变量必须要显示初始化 final修饰引用变量不能被重新赋值但是可以改变引用对象的内容分(只要地址值不变) final修

Java 单例

最近在网上看到一篇关于 Java 单例的创建问题,虽然是一个 Java 程序员,但是到现在还没有真正的深入了解到 Java 的原理和机制.所以每每看到这样能够"真正"接触 Java 的机会内心总是充满了欣喜.记录下,以后备用. 懒汉模式 public class Singlton{ private static Singleton instance; private Singlton(){} public static Singlton getInstance(){ if(instac

Java——单例设计模式

设计模式:解决某一类问题最行之有效的方法.Java中23种设计模式:单例设计模式:解决一个类在内存中只存在一个对象. 想要保证对象唯一.1,为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象.3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式 这三部怎么用代码体现呢?1,将构造函数私有化.2,在类中创建一个本类对象.3,提供一个方法可以获取到该类对象. 对于事物该怎么描述,还怎么描述.当需要将该事物的对象

Java设计模式中的单例设计

/** * 单例设计模式 * 应用场合:只需要一个对象的 * 作用:保证整个应用程序中某个实例有且只有一个 * 类型有:饿汉模式.懒汉模式 * 下面的例子是一个饿汉模式的例子 */ class SingleDemo { // 1.将构造方法私有化,不允许外部直接创建使用 private SingleDemo() {} // 2.创建类的唯一实例,使用private static修饰 private static SingleDemo instance = new SingleDemo(); //

java单例-积木系列

一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档. 懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒汉,因为它是属于延迟加载这个实例的,也就是说不用到的时候,不实例化对象的. public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInst

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

设计模式:解决某一类问题最行之有效的方法. java中23种设计模式. 单例设计模式:解决一类在内存中只存在一个对象. Runtime()方法就是单例设计模式进行设计的. 解决的问题:保证一个类在内存中的对象唯一性. 比如:多程序读取一个配置文件时,建议配置文件封装成对象.会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的. 1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象. 2.还为了让其他程序可以访问该类对象,只好在本类中自定

黑马程序员--Java基础学习笔记【单例设计模式、网络编程、反射】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 设计模式分类: 创建模式:是对类的实例化过程的抽象化,又分为类创建模式和对象创建模式 类创建模式:工厂方法模式 对象-:简单工厂(静态工厂方法)模式.抽象工厂模式.单例模式.建造模式- 结构模式:描述如何将类或者对象结合在一起形成更大的结构 适配器模式.缺省模式.合成模式.装饰模式(包装模式).门面模式- 行为模式:对不同的对象之间划分责任和算法的抽象化 不变模式.策略模式.迭代子模式.命令模

java:单例的理解

前言:Java的单例经常用到,今天发现自己有一点新的认识. 懒汉式单例 package com.mwq.singleton; public class Singleton1 { private Singleton1() { } private static Singleton1 single = null; public static Singleton1 getInstance() { if (single == null) { return new Singleton1(); } retur

Java 单例总结

1:懒汉式,不保证线程安全 package com.yan.singleton; public class LazySingleton { private static final LazySingleton instance = null; private LazySingleton(){} public static LazySingleton getLazySingleton(){ if(null==instance){ return new LazySingleton(); } retu