java 单例 实现_JAVA单例的几种实现

一、饿汉式

public class Singleton{

//定义一个变量来存储创建好的类实例,直接在这里创建,只能创建一次

private static Singleton uniqueInstance = new Singleton();

//私有化构造方法,可以在内部控制创建实例的数目

private Singleton(){

//

}

//定义一个方法来为客户端提供类实例

public static Singleton getInstance(){

return uniqueInstance;

}

}

最简单的单例实现,典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要在判断了,节省了运行时间。

二、懒汉式

public class Singleton{

//定义一个变量来存储创建好的实例

private static Singleton uniqueInstance = null;

//私有化构造方法,可以在内部控制创建实例的数目

private Singleton(){

//

}

//定义一个方法来为客户端提供类实例

public static synchronized Singleton getInstance(){

//判断存储实例的变量是否有值

if(uniqueInstance == null){

//如果没有,就创建一个类实例,并把值赋给存储类实例的变量

uniqueInstance = new Singleton();

}

//如果有就直接使用

return uniqueInstance();

}

}

时间-空间上刚好与饿汉相反,可以实现延迟加载,但是需要注意多线程调用的效率问题。

三、内部类实现

public class Singleton{

/*类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑

*定关系,而且在由在调用时才会装载,从而实现了延迟加载

*/

private static class SingletonHolder{

//静态初始化器,由JVM来保证线程安全

private static Singleton instance = new Singleton();

}

private Singleton(){

}

private static Singleton getInstance(){

return SingletonHolder.instance;

}

}

由虚拟机来保证它的线程安全性。

四、缓存方式

import java.util.* ;

public class SingletonCache{

private final static String DEFAULT_KEY = "One" ;

private static Map map = new HashMap

private SingletonCache(){

//

}

public static SingletonCache getInstance(){

SingletonCache instance = (SingletonCache)map.get(DEFAULT_KEY) ;

if(instance==null){

instance = new SingletonCache() ;

map.put(DEFAULT_KEY,instance) ;

}

}

}

该种实现方式可以扩展为实例数量固定的情形,如要求某个类最多创建3个实例的情形。

五、枚举方式

public enum Singleton{

//定义一个枚举的元素,它代表了Singleton的一个实例

uniqueInstance ;

private Singleton() {

//准备初始化工作

}

public void singletonOperate(){

//功能处理

}

}

最简单、高效、安全的实现方式。

六、双重加锁

public class Singleton{

private volatile static Singleton instance = null ;

private Singleton(){

}

public static Singleton getInstance(){

//先检查实例是否存在,如果不存在才进入下面的同步块

if(instance == null){

//同步块,线程安全地创建实例

synchronized(Singleton.class){

//再次检查实例是否存在,如果不存在才真正地创建实例

if(instance == null){

instance = new Singleton() ;

}

}

}

return instance ;

}

}

使用“双重检查加锁”的方式来实现,就可以既实现线程安全,又能够使性能不受到大的影响。所谓双重检查加锁机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。

双重检查加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值