java中的单例模式的代码怎么写 (java中的基本数据类型有哪些)

本文目录导航:

java中的单例模式的代码怎么写

我从我的博客里把我的文章粘贴过来吧,对于单例模式模式应该有比较清楚的解释:单例模式在我们日常的项目中十分常见,当我们在项目中需要一个这样的一个对象,这个对象在内存中只能有一个实例,这时我们就需要用到单例。

一般说来,单例模式通常有以下几种:1.饥汉式单例public class Singleton {private Singleton(){};private static Singleton instance = new Singleton();public static Singleton getInstance(){return instance;}}这是最简单的单例,这种单例最常见,也很可靠!它有个唯一的缺点就是无法完成延迟加载——即当系统还没有用到此单例时,单例就会被加载到内存中。

在这里我们可以做个这样的测试:将上述代码修改为:public class Singleton {private Singleton(){(createSingleton);};private static Singleton instance = new Singleton();public static Singleton getInstance(){return instance;}public static void testSingleton(){(CreateString);}}而我们在另外一个测试类中对它进行测试(本例所有测试都通过Junit进行测试)public class TestSingleton {@Testpublic void test(){();}}输出结果:createSingletonCreateString我们可以注意到,在这个单例中,即使我们没有使用单例类,它还是被创建出来了,这当然是我们所不愿意看到的,所以也就有了以下一种单例。

2.懒汉式单例public class Singleton1 {private Singleton1(){(createSingleton);}private static Singleton1 instance = null;public static synchronized Singleton1 getInstance(){return instance==null?new Singleton1():instance;}public static void testSingleton(){(CreateString);}}上面的单例获取实例时,是需要加上同步的,如果不加上同步,在多线程的环境中,当线程1完成新建单例操作,而在完成赋值操作之前,线程2就可能判断instance为空,此时,线程2也将启动新建单例的操作,那么多个就出现了多个实例被新建,也就违反了我们使用单例模式的初衷了。

我们在这里也通过一个测试类,对它进行测试,最后面输出是CreateString可以看出,在未使用到单例类时,单例类并不会加载到内存中,只有我们需要使用到他的时候,才会进行实例化。

这种单例解决了单例的延迟加载,但是由于引入了同步的关键字,因此在多线程的环境下,所需的消耗的时间要远远大于第一种单例。

我们可以通过一段测试代码来说明这个问题。

public class TestSingleton {@Testpublic void test(){long beginTime1 = ();for(int i=0;i<;i++){();}(单例1花费时间:+(()-beginTime1));long beginTime2 = ();for(int i=0;i<;i++){();}(单例2花费时间:+(()-beginTime2));}}最后输出的是:单例1花费时间:0单例2花费时间:10可以看到,使用第一种单例耗时0ms,第二种单例耗时10ms,性能上存在明显的差异。

为了使用延迟加载的功能,而导致单例的性能上存在明显差异,是不是会得不偿失呢?是否可以找到一种更好的解决的办法呢?既可以解决延迟加载,又不至于性能损耗过多,所以,也就有了第三种单例:3.内部类托管单例public class Singleton2 {private Singleton2(){}private static class SingletonHolder{private static Singleton2 instance=new Singleton2();}private static Singleton2 getInstance(){return ;}}在这个单例中,我们通过静态内部类来托管单例,当这个单例被加载时,不会初始化单例类,只有当getInstance方法被调用的时候,才会去加载SingletonHolder,从而才会去初始化instance。

并且,单例的加载是在内部类的加载的时候完成的,所以天生对线程友好,而且也不需要synchnoized关键字,可以说是兼具了以上的两个优点。

4.总结一般来说,上述的单例已经基本可以保证在一个系统中只会存在一个实例了,但是,仍然可能会有其他的情况,导致系统生成多个单例,请看以下情况:public class Singleton3 implements Serializable{private Singleton3(){}private static class SingletonHolder{private static Singleton3 instance = new Singleton3();}public static Singleton3 getInstance(){return ;}}通过一段代码来测试:@Testpublic void test() throws Exception{Singleton3 s1 = null;Singleton3 s2 = ();//1.将实例串行话到文件FileOutputStream fos = new FileOutputStream();ObjectOutputStream oos =new ObjectOutputStream(fos);(s2);();();//2.从文件中读取出单例FileInputStream fis = new FileInputStream();ObjectInputStream ois = new ObjectInputStream(fis);s1 = (Singleton3) ();if(s1==s2){(同一个实例);}else{(不是同一个实例);}}输出:不是同一个实例可以看到当我们把单例反序列化后,生成了多个不同的单例类,此时,我们必须在原来的代码中加入readResolve()函数,来阻止它生成新的单例public class Singleton3 implements Serializable{private Singleton3(){}private static class SingletonHolder{private static Singleton3 instance = new Singleton3();}public static Singleton3 getInstance(){return ;}//阻止生成新的实例public Object readResolve(){return ;}}再次测试时,就可以发现他们生成的是同一个实例了。

java中的单例模式的代码怎么写 (java中的基本数据类型有哪些)

如何解读java中的设计模式下的getinstance()方法?

单例模式在Java中是一种设计模式,确保一个类只创建一个实例,并提供一个全局访问点,使得其他对象可以访问该实例。

这种模式有助于节省资源并简化管理,避免创建过多对象,特别是在需要控制全局状态的应用中。

实现单例模式的关键在于确保实例化过程的唯一性与一致性。

接下来,我们将探讨使用枚举实现单例模式的优点与示例代码。

使用枚举实现单例模式是一个简洁且安全的方式。

每个枚举常量都是该枚举类型的唯一实例,因此,只需定义枚举常量作为单例对象,即可确保全局唯一性。

以下是枚举实现单例模式的代码示例:

javapublic enum Singleton {INSTANCE;}

由于枚举常量的唯一性,`INSTANCE`成为了`Singleton`的唯一实例。使用枚举实现单例模式具有以下优点:

接下来,我们将回答一些关于单例模式的问题,以深入理解其用法与特点。

问题与答案

1)什么是单例模式?

单例模式是一种设计模式,确保一个类只有一个实例,并提供全局访问点以供其他对象访问。

这种模式用于控制全局资源的访问,如日志系统、数据库连接池等。

2)如何实现单例模式?

实现单例模式的方式有多种,包括饿汉式、懒汉式、双重检查锁定和静态内部类等。

其中,饿汉式和静态内部类在多线程环境下具有线程安全性,而懒汉式和双重检查锁定则需要额外的同步措施来确保线程安全。

3)为什么使用单例模式?

使用单例模式可以减少资源消耗,避免创建不必要的对象实例,特别是在需要管理全局状态的应用中。

它有助于简化代码、提高性能,并确保全局资源的一致性。

4)单例模式有哪些优缺点?

优点:简化资源管理、减少内存消耗、提高系统性能、确保全局资源一致性。

缺点:违反开闭原则,单例类的修改可能影响所有使用该类的模块,导致代码耦合度增加;可能影响系统可测试性。

5)如何保证单例模式的线程安全?

可以通过同步关键字(如`synchronized`)、volatile关键字、静态内部类等方式实现线程安全的单例模式。

其中,饿汉式和静态内部类是最常见的线程安全实现方式。

单例模式在Spring框架中的应用

在Spring框架中,单例模式用于管理Bean的实例化与生命周期。

Spring默认将大部分Bean设置为单例模式,确保全局唯一性。

Spring通过作用域、延迟初始化和生命周期回调等功能,提供了一种灵活且可靠的Bean管理方式。

1)Bean的作用域

默认情况下,Spring中的Bean是单例的,意味着它们只实例化一次,可供多个对象共享。

Spring还支持其他作用域,如原型、请求、会话和全局会话。

2)生命周期回调

Spring提供多个回调方法,用于管理Bean的生命周期,包括初始化前、初始化后、销毁前和销毁后等。

通过实现这些回调方法,可以对Bean的生命周期进行精细控制,提高应用的可靠性和稳定性。

在单例模式下,Bean的初始化和销毁仅发生一次。

综上所述,单例模式在Java和Spring框架中具有广泛的应用,提供了高效、简洁且安全的实例化与管理方式。

理解单例模式的实现与特性,将有助于构建更加灵活和可维护的系统。

设计模式之单例模式

单例设计模式理解起来非常简单。

一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫单例模式。

下面的示例中如果每个类都创建一个 Logger 实例,就可能造成日志内容被覆盖的情况。

如果有些数据在系统中只应保存一份,那就比较适合设计为单例类。

比如,配置信息类,全局 ID 生成器等。

要实现一个单例,我们要考虑以下几点:

懒汉式相对于饿汉式的优势是「支持延迟加载」 。

但缺点也很明显,因为使用了 synchronized 关键字导致这个方法的「并发度很低」 。

如果这个单例类偶尔会被用到,那这种实现方式还可以接受。

但是,如果频繁地用到,就会导致性能瓶颈,这种实现方式就不可取了。

这是一种既支持延迟加载、又支持高并发的单例实现方式。

在 java1.5 以下 instance = new Singleton(); 有指令重排问题,需要给 instance 成员变量加上 volatile 关键字,java1.5 之后不会再这个问题。

这种方式利用了 Java 的静态内部类,有点类似饿汉式,但又能做到了延迟加载。

当外部类 Singleton 被加载的时候,并不会创建 SingletonHolder 实例对象。

只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时候才会创建 instance。

insance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。

所以,这种实现方法既保证了线程安全,又能做到延迟加载。

这是一种最简单的实现方式,基于枚举类型的单例实现。

这种实现方式是通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。

上面的单例类对象是进程唯一的,一个进程只能有一个单例对象。那如何实现一个线程唯一的单例呢?

假设 IdGenerator 是一个线程唯一的单例类。

在线程 A 内,我们可以创建一个单例对象 a。

因为线程内唯一,在线程 A 内就不能再创建新的 IdGenerator 对象了,而线程间可以不唯一,所以,在另外一个线程 B 内,我们还可以重新创建一个新的单例对象 b。

我们通过一个 ConcurrentHashMap 来存储对象,其中 key 是线程 ID,value 是对象。

这样我们就可以做到,不同的线程对应不同的对象,同一个线程只能对应一个对象。

实际上,Java 语言本身提供了 ThreadLocal 工具类,可以更加轻松地实现线程唯一单例。

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

53阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

44阅读

php一句话木马,一句话木马ctf

2026年10月05日

48阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

50阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

47阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

42阅读