Java实现单例模式
java 单例写法

java 单例写法在Java编程中,单例模式是一种设计模式,意味着仅仅存在一个实例对象。
单例模式是一种常见的面向对象编程技巧,在很多情况下,它可以有效地提高程序的性能并且降低系统的复杂度。
下面我们来学习一下Java单例写法,并进行阐述。
第一步:通过私有构造函数来防止其他类实例化单例类在Java中,我们需要通过私有构造函数来防止外部类的实例化。
这里我们提供一个例子,代码如下:public class Singleton {private static Singleton instance;private Singleton() { }public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}在上述代码中,我们通过私有构造函数来防止其他类实例化Singleton类。
由于我们只需要一个实例,因此我们对实例对象进行了私有化。
这样,我们便可以使用getInstance()函数来获取类的实例,从而确保该类只存在一个实例。
第二步:实现懒汉式单例懒汉式单例模式是指在需要时创建实例。
在该模式种,单例类的实例不会在程序启动时就创建,而是在调用getInstance()方法时创建。
代码如下:public class LazySingleton {private static volatile LazySingleton instance =null;private LazySingleton() { }public static LazySingleton getInstance() {if (instance == null) {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}}return instance;}}在上述代码中,getInstance()函数通过检查instance是否为空来实现懒汉式单例模式。
java单例模式的实际应用

java单例模式的实际应用Java单例模式是一种常用的设计模式,它可以保证在一个JVM中只存在一个实例对象。
在实际应用中,单例模式可以解决一些特定场景下的问题,提高系统的性能和效率。
一、数据库连接池在使用数据库连接时,每次都需要创建连接对象和释放连接对象,这个过程比较耗时。
如果每次都创建新的连接对象,会导致系统性能下降。
这时可以使用单例模式来创建一个数据库连接池,保证系统中只有一个连接池对象,通过连接池管理连接的创建和释放,提高了系统的性能和效率。
二、日志记录器在系统开发中,通常需要记录系统的运行日志,以供日后排查问题或者监控系统运行状态。
使用单例模式创建一个日志记录器对象,可以保证系统中只有一个日志记录器实例,所有的日志记录都通过这个实例进行操作,便于集中管理和统一处理。
三、配置文件管理器在系统开发中,通常需要读取配置文件中的参数或者属性,以便灵活配置系统的行为。
使用单例模式创建一个配置文件管理器对象,可以保证系统中只有一个配置文件管理器实例,所有的配置文件读取操作都通过这个实例进行,便于统一管理和维护。
四、线程池在多线程编程中,线程的创建和销毁都需要耗费一定的系统资源。
如果每次都创建新的线程,会导致系统资源的浪费。
使用单例模式创建一个线程池对象,可以保证系统中只有一个线程池实例,通过线程池管理线程的创建和销毁,提高了系统的性能和效率。
五、缓存管理器在系统开发中,通常需要缓存一些数据,以提高系统的访问速度。
使用单例模式创建一个缓存管理器对象,可以保证系统中只有一个缓存管理器实例,通过缓存管理器来管理缓存的读取、存储和更新,提高了系统的性能和效率。
六、打印机管理器在某些场景下,需要使用打印机进行打印操作。
如果每次都新建一个打印机对象,会导致系统资源的浪费。
使用单例模式创建一个打印机管理器对象,可以保证系统中只有一个打印机管理器实例,通过打印机管理器来管理打印机的使用,提高了系统的性能和效率。
七、窗口管理器在图形界面编程中,通常需要使用窗口进行用户交互。
Java设计模式之《单例模式》及应用场景

Java设计模式之《单例模式》及应⽤场景所谓单例,指的就是单实例,有且仅有⼀个类实例,这个单例不应该由⼈来控制,⽽应该由代码来限制,强制单例。
单例有其独有的使⽤场景,⼀般是对于那些业务逻辑上限定不能多例只能单例的情况,例如:类似于计数器之类的存在,⼀般都需要使⽤⼀个实例来进⾏记录,若多例计数则会不准确。
其实单例就是那些很明显的使⽤场合,没有之前学习的那些模式所使⽤的复杂场景,只要你需要使⽤单例,那你就使⽤单例,简单易理解。
所以我认为有关单例模式的重点不在于场景,⽽在于如何使⽤。
1、常见的单例模式有两种创建⽅式:所谓饿懒汉式与饿汉式(1)懒汉式 何为懒?顾名思义,就是不做事,这⾥也是同义,懒汉式就是不在系统加载时就创建类的单例,⽽是在第⼀次使⽤实例的时候再创建。
详见下⽅代码⽰例:public class LHanDanli {//定义⼀个私有类变量来存放单例,私有的⽬的是指外部⽆法直接获取这个变量,⽽要使⽤提供的公共⽅法来获取private static LHanDanli dl = null;//定义私有构造器,表⽰只在类内部使⽤,亦指单例的实例只能在单例类内部创建private LHanDanli(){}//定义⼀个公共的公开的⽅法来返回该类的实例,由于是懒汉式,需要在第⼀次使⽤时⽣成实例,所以为了线程安全,使⽤synchronized关键字来确保只会⽣成单例public static synchronized LHanDanli getInstance(){if(dl == null){dl = new LHanDanli();}return dl;}}(2)饿汉式 ⼜何为饿?饿者,饥不择⾷;但凡有⾷,必急⾷之。
此处同义:在加载类的时候就会创建类的单例,并保存在类中。
详见下⽅代码⽰例:public class EHanDanli {//此处定义类变量实例并直接实例化,在类加载的时候就完成了实例化并保存在类中private static EHanDanli dl = new EHanDanli();//定义⽆参构造器,⽤于单例实例private EHanDanli(){}//定义公开⽅法,返回已创建的单例public static EHanDanli getInstance(){return dl;}}2、双重加锁机制 何为双重加锁机制? 在懒汉式实现单例模式的代码中,有使⽤synchronized关键字来同步获取实例,保证单例的唯⼀性,但是上⾯的代码在每⼀次执⾏时都要进⾏同步和判断,⽆疑会拖慢速度,使⽤双重加锁机制正好可以解决这个问题:public class SLHanDanli {private static volatile SLHanDanli dl = null;private SLHanDanli(){}public static SLHanDanli getInstance(){if(dl == null){synchronized (SLHanDanli.class) {if(dl == null){dl = new SLHanDanli();}}}return dl;}}看了上⾯的代码,有没有感觉很⽆语,双重加锁难道不是需要两个synchronized进⾏加锁的吗? ...... 其实不然,这⾥的双重指的的双重判断,⽽加锁单指那个synchronized,为什么要进⾏双重判断,其实很简单,第⼀重判断,如果单例已经存在,那么就不再需要进⾏同步操作,⽽是直接返回这个实例,如果没有创建,才会进⼊同步块,同步块的⽬的与之前相同,⽬的是为了防⽌有两个调⽤同时进⾏时,导致⽣成多个实例,有了同步块,每次只能有⼀个线程调⽤能访问同步块内容,当第⼀个抢到锁的调⽤获取了实例之后,这个实例就会被创建,之后的所有调⽤都不会进⼊同步块,直接在第⼀重判断就返回了单例。
java笔试题大集合及答案

java笔试题大集合及答案# Java笔试题大集合及答案1. Java中接口和抽象类的区别是什么?- 接口和抽象类都是抽象的,不能直接实例化。
- 接口中所有的方法默认是public的,而抽象类可以包含非public的成员。
- 一个类可以实现多个接口,但只能继承一个抽象类。
- 接口中不能包含构造方法,而抽象类可以。
- 接口中的字段默认是public static final的,而抽象类中的字段可以是任意类型。
2. Java中如何实现单例模式?- 单例模式确保一个类只有一个实例,并提供一个全局访问点。
- 可以通过私有化构造方法,提供一个私有静态变量来保存实例,并提供一个公有静态方法来获取实例。
3. Java中集合框架的层次结构是怎样的?- 集合框架分为两大类:单元素集合和复合元素集合。
- 单元素集合包括List、Set和Queue。
- 复合元素集合包括Map。
- 每个接口都有多个实现类,如ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。
4. Java中如何实现多线程?- 可以通过继承Thread类并重写run方法来实现。
- 也可以通过实现Runnable接口并重写run方法,然后创建Thread对象来实现。
- Java 5引入了Executor框架,可以更方便地管理线程。
5. Java中异常处理的机制是什么?- Java使用try-catch-finally块来处理异常。
- try块中编写可能抛出异常的代码。
- catch块中编写处理异常的代码。
- finally块中的代码无论是否发生异常都会执行。
6. Java中StringBuffer和StringBuilder的区别是什么?- StringBuffer是线程安全的,而StringBuilder不是。
- StringBuffer的方法是同步的,StringBuilder的方法不是。
- 在单线程环境下,StringBuilder的性能优于StringBuffer。
Java使用Enum实现单例模式

Java使⽤Enum实现单例模式在中介绍了单例模式有五种写法:懒汉、饿汉、双重检验锁、静态内部类、枚举。
如果涉及到反序列化创建对象时推荐使⽤枚举的⽅式来实现单例,因为Enum能防⽌反序列化时重新创建新的对象。
本⽂介绍 Enum 的使⽤⽅式。
public enum SingletonEnum{INSTANCE;}通过SingletonEnum.INSTANCE来访问实例,使⽤⽅式很简单. 然⽽就这么简单的话也没有更多意义,具体的使⽤⽅式如下:public enum SingletonEnum {INSTANCE;int value;// 这⾥我们可以⾃定义构造函数.private SingletonEnum() {value = 1;System.out.println("INSTANCE now created!");}public int getValue() {return value;}public void setValue(int value) {this.value = value;}}调⽤:System.out.println("start get instance!");SingletonEnum singleton = SingletonEnum.INSTANCE;System.out.println(singleton.getValue());singleton.setValue(2);System.out.println(singleton.getValue());输⼊结果为:start get instance!INSTANCE now created!12上⾯的SingletonEnum的定义利⽤的enum是⼀种特殊的class.代码中的第⼀⾏INSTANCE会被编译器编译为SingletonEnum本⾝的⼀个对象.当第⼀次访问SingletonEnum.INSTANCE时会创建该对象,并且enum变量的创建是线程安全的.1.2.。
java几种常用设计模式简单示例

java⼏种常⽤设计模式简单⽰例1.单例设计模式所谓单例设计模式简单说就是⽆论程序如何运⾏,采⽤单例设计模式的类(Singleton类)永远只会有⼀个实例化对象产⽣。
具体实现步骤如下:(1) 将采⽤单例设计模式的类的构造⽅法私有化(采⽤private修饰)。
(2) 在其内部产⽣该类的实例化对象,并将其封装成private static类型。
(3) 定义⼀个静态⽅法返回该类的实例。
⽰例代码如下:class Singleton {private static Singleton instance = new Singleton();// 在内部产⽣本类的实例化对象public static Singleton getInstance() { // 通过静态⽅法返回instance对象return instance;}private Singleton() { // 将构造⽅法封装为私有化}public void print() {System.out.println("Hello World");}}public class SingletonDemo {public static void main(String args[]) {Singleton s1 = null; // 声明对象Singleton s2 = null; // 声明对象Singleton s3 = null; // 声明对象s1 = Singleton.getInstance(); // 取得实例化对象s2 = Singleton.getInstance(); // 取得实例化对象s3 = Singleton.getInstance(); // 取得实例化对象s1.print(); // 调⽤⽅法s2.print(); // 调⽤⽅法s3.print(); // 调⽤⽅法}} ⼀、单例模式的介绍Singleton是⼀种创建型模式,指某个类采⽤Singleton模式,则在这个类被创建后,只可能产⽣⼀个实例供外部访问,并且提供⼀个全局的访问点⼆、单例模式的实现实现的⽅式有如下四种:/**** 单例模式的实现:饿汉式,线程安全但效率⽐较低*/public class SingletonTest {private SingletonTest() {}private static final SingletonTest instance = new SingletonTest();public static SingletonTest getInstancei() {return instance;}}/*** 单例模式的实现:饱汉式,⾮线程安全**/public class SingletonTest {private SingletonTest() {}private static SingletonTest instance;public static SingletonTest getInstance() {if (instance == null)instance = new SingletonTest();return instance;}}/*** 线程安全,但是效率⾮常低* @author vanceinfo**/public class SingletonTest {private SingletonTest() {}private static SingletonTest instance;public static synchronized SingletonTest getInstance() {if (instance == null)instance = new SingletonTest();return instance;}}/*** 线程安全并且效率⾼**/public class SingletonTest {private static SingletonTest instance;private SingletonTest() {}public static SingletonTest getIstance() {if (instance == null) {synchronized (SingletonTest.class) {if (instance == null) {instance = new SingletonTest();}}}return instance;}}2.⼯⼚设计模式程序在接⼝和⼦类之间加⼊了⼀个过渡端,通过此过渡端可以动态取得实现了共同接⼝的⼦类实例化对象。
java单例模式实现方式以及应用场景

java单例模式实现方式以及应用场景1.引言1.1 概述单例模式是一种常用的设计模式,它确保类只能创建一个实例,并提供一种全局访问的方式。
在Java中,单例模式可以通过不同的实现方式来达到这个目的。
本文将介绍几种常见的Java单例模式实现方式,并探讨它们的应用场景。
单例模式的主要目的是为了节约系统资源,比如数据库连接池、线程池等,这些资源在整个系统中只需要一个实例就可以满足需求。
同时,单例模式也可以保证数据的一致性,避免多个实例引发的数据不一致问题。
本文将详细介绍以下几种Java单例模式的实现方式:1. 懒汉式:在第一次使用时才创建实例。
懒汉式的实现相对简单,但在多线程环境下需要考虑线程安全的问题。
2. 饿汉式:在类加载时就创建实例。
饿汉式的实现较为简单,可以避免多线程环境下的线程安全问题,但可能造成资源的浪费。
3. 双重检验锁(Double Checked Locking):结合了懒汉式和饿汉式的优点,既能在需要时才创建实例,又能保证线程安全。
4. 静态内部类:利用Java的类加载机制,实现了延迟加载,并且保证了线程安全。
以上是几种常见的单例模式实现方式,不同的实现方式适用于不同的场景。
在接下来的章节中,我们将详细探讨它们的应用场景,并总结各自的优缺点。
1.2 文章结构本文将从以下几个方面来探讨和讲解Java单例模式的实现方式以及应用场景:1. 引言:在引言部分,我们将对单例模式进行概述,说明其作用和重要性,并介绍本文的结构和目的。
2. 正文:2.1 单例模式的定义和作用:在这一部分,我们将详细阐述单例模式的概念和作用。
我们将解释单例模式的定义,并探讨它为什么在软件开发中如此重要。
我们还将说明单例模式的特点和优点。
2.2 单例模式的实现方式:本节将详细介绍几种常用的单例模式实现方式。
我们将分别讨论懒汉式和饿汉式两种最常见的实现方式,并对它们的优缺点进行比较和讨论。
此外,我们还将介绍线程安全和非线程安全的单例模式实现方式,并对它们的适用场景进行说明。
单例的七种写法

单例的七种写法单例模式是一种常用的设计模式,它保证一个类只有一个实例,并提供一个全局访问点。
在实际开发中,我们经常会遇到需要使用单例模式的场景。
在Java中,单例模式有七种写法,下面我们来逐一介绍。
1. 饿汉式单例模式饿汉式单例模式指的是在类加载时就实例化了该类的唯一实例。
这种写法没有使用锁,因此线程安全。
代码如下:```public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}}```2. 懒汉式单例模式懒汉式单例模式指的是在第一次使用时才实例化该类的唯一实例。
这种写法需要使用同步锁,因此效率较低。
代码如下:```public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}```3. 双重校验锁单例模式双重校验锁单例模式指的是先判断实例是否存在,若不存在,则进入同步块进行实例化,提高效率。
这种写法需要使用volatile修饰实例,保证线程安全。
代码如下:public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}}```4. 静态内部类单例模式静态内部类单例模式指的是利用静态内部类的加载机制实现单例。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2009年05月14日星期四 12:00Java设计模式圣经连载(04)-单例模式单例模式是一种常见的设计模式,在《Java与模式》一书中,阎宏博士对单例模式做了全面的总结。
单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
说明:一下的代码来自阎宏博士的《Java与模式》一书,其中对一些类的写法做调整(符合Java1.5的习惯),另外还加了测试方法。
一、懒汉式单例在类被加载的时候,唯一实例已经被创建。
这个设计模式在Java中容易实现,在别的语言中难以实现。
/*** Created by IntelliJ IDEA.* User: leizhimin* Date: 2007-9-11* Time: 14:57:08* <<Java与模式>> 单例模式-懒汉式单例*/public class LazySingleton {/*** 私有静态对象,加载时候不做初始化*/private static LazySingleton m_intance=null;/*** 私有构造方法,避免外部创建实例*/private LazySingleton(){}/*** 静态工厂方法,返回此类的唯一实例.* 当发现实例没有初始化的时候,才初始化.* @return LazySingleton*/synchronized public static LazySingleton getInstance(){ if(m_intance==null){m_intance=new LazySingleton();}return m_intance;}}二、饿汉式单例在类加载的时候不创建单例实例。
只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。
/*** Created by IntelliJ IDEA.* User: leizhimin* Date: 2007-9-11* Time: 14:45:25* <<Java与模式>> 单例模式-饿汉式单例*/public class EagerSingleton {/*** 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象*/private static final EagerSingleton m_instance = new EagerSingleton();/*** 私有构造方法,避免外部创建实例*/private EagerSingleton() {}/*** 静态工厂方法,返回此类的唯一实例.* @return EagerSingleton*/public static EagerSingleton getInstance() {return m_instance;}}三、登记式单例这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。
/*** Created by IntelliJ IDEA.* User: leizhimin* Date: 2005-9-11* Time: 15:20:16* <<Java与模式>> 单例模式- 登记式单例*/public class RegSingleton {/*** 登记薄,用来存放所有登记的实例*/private static Map<String, RegSingleton> m_registry = new HashMap();//在类加载的时候添加一个实例到登记薄static {RegSingleton x = new RegSingleton();m_registry.put(x.getClass().getName(), x);}/*** 受保护的默认构造方法*/protected RegSingleton() {}/*** 静态工厂方法,返回指定登记对象的唯一实例;* 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回* @param name* @return RegSingleton*/public static RegSingleton getInstance(String name) {if (name == null) {name = "RegSingleton";}if (m_registry.get(name) == null) {try {m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}return m_registry.get(name);}/*** 一个示意性的商业方法* @return String*/public String about() {return "Hello,I am RegSingleton!";}}四、单例模式的一个应用该应用是配置文件管理类。
为了本例能正确运行,我在C盘下先建立了一个xxxx.properties文件,内容如下:-------------------user=rootpassword=leizhimin这个配置文件管理类的代码如下:/*** Created by IntelliJ IDEA.* User: leizhimin* Date: 2005-9-11* Time: 15:55:01* 单例模式应用-单例类应用-配置文件管理*/public class ConfigManager {/*** 属性文件全名*/private static final String PFILE = "C:\\xxx.properties"; /*** 对应于属性文件的文件对象变量*/private File m_file = null;/*** 属性文件的最后修改日期*/private long m_lastModifiedTime = 0;/*** 属性文件所对应的属性对象变量*/private Properties m_props = null;/*** 本类可能存在的唯一的一个实例*/private static ConfigManager m_instance = new ConfigManager();/*** 私有构造子,用以保证外界无法直接实例化*/private ConfigManager() {m_file = new File(PFILE);m_lastModifiedTime = m_stModified(); if (m_lastModifiedTime == 0) {System.err.println(PFILE + " file does notexist!");}m_props = new Properties();try {m_props.load(new FileInputStream(PFILE));} catch (IOException e) {e.printStackTrace();}}/*** 静态工厂方法** @return ConfigManager*/synchronized public static ConfigManager getInstance() { return m_instance;}/*** 获取属性配置项的值** @param name* @param defaultVal* @return Object*/public final Object getConfigItem(String name, Object defaultVal) {long newTime = m_stModified();if (newTime == 0) {//属性文件不存在if (m_lastModifiedTime == 0) {System.err.println(PFILE + " file does not exist!");} else {System.err.println(PFILE + " file was deleted!");}return defaultVal;} else if (newTime > m_lastModifiedTime) {m_props.clear();try {m_props.load(new FileInputStream(PFILE)); } catch (IOException e) {e.printStackTrace();}}m_lastModifiedTime = newTime;Object val = m_props.getProperty(name);if (val == null) {return defaultVal;} else {return val;}}}测试配置文件类:/*** Created by IntelliJ IDEA.* User: leizhimin* Date: 2007-9-11* Time: 16:42:45* 配置文件管理类测试*/public class Test_ConfigManager {public static void main(String[] args) {ConfigManager cfgm = ConfigManager.getInstance();Object val1 = cfgm.getConfigItem("sdf", "leizhimin"); Object val2 = cfgm.getConfigItem("user", "leizhimin"); System.out.println(val1.toString());System.out.println(val2.toString());}}运行结果:leizhiminrootProcess finished with exit code 0五、笔者写的一个JDBC数据库工具类的单例实现/*** Created by IntelliJ IDEA.* User: leizhimin* Date: 2005-9-11* Time: 18:04:46* 单例模式在JDBC编程中的应用,用于设计数据库工具类*/public class DBUtil {//单一实例private static final DBUtil _instance = new DBUtil();//数据源的JNDIprivate static final String datasource = "java:comp/env/jdbc/zvfims";/*** 私有构造方法,防止外部实例化*/private DBUtil() {}/*** 数据库工具类实例工厂** @return DBUtil*/public DBUtil getInstance() {return _instance;}/*** 业务方法:用于获取数据库连接** @return Connection*/public Connection makeConnection() {Connection conn = null;try {Context ctx = new InitialContext();DataSource ds = (DataSource)ctx.lookup(datasource);conn = ds.getConnection();} catch (NamingException e) {System.out.println("获取数据源异常,请AppServer的JNDI数据源配置!");e.printStackTrace();} catch (SQLException e) {System.err.println("获取数据库连接发生异常!");e.printStackTrace();}return conn;}}通过这个单例类和开放的业务方法,可以为整个系统应用提供数据库连接。