java单态类_java单例类的几种实现

一,最简单的方式

public classSingleton{privateSingleton(){};private static Singleton instance = newSingleton();public staticSingleton getInstance(){returninstance;

}

}

首先构造函数声明为private,防止被外部创建该类的实例。声明一个static的成员变量instance并分配实例,当Singleton类被加载时,instance便会被创建,可以通过静态方法getInstance方法获取到该实例。

优点是实现简单,且没有线程安全问题。缺点是Singleton被引用时instance实例就已经创建,即使实例并没有用到。

二,懒加载的单例类

public classSingleton{privateSingleton(){};private static Singleton instance = null;public static synchronizedSingleton getInstance(){if(instance == null){

instance= newSingleton();

}returninstance;

}

}

因为instance初始值为null,所以在Singleton被加载的时候,并不会实例化,只有调用getInstance方法的时候才会创建实例。为了防止多线程并发调用getInstance方法时instance被多次创建,所以使用synchronized关键字进行线程同步。

该实现缺点是,每次调用getInstance方法都要进行线程同步,影响并发量。

三,改进懒加载的单例类

public classSingleton{privateSingleton(){};private static volatile Singleton instance = null;public staticSingleton getInstance(){if(instance == null){synchronized(Singleton.class){if(instance == null){

instance= newSingleton();

}

}

}returninstance;

}

}

通过双检索的方式进行优化,只有在intance没有值时才进行线程同步,此后会直接返回实例。需要注意的是,在synchronized代码块中需要再判断一次instance是否为null,防止多个线程同时通过了第一个为null的判断。

还需要注意的是,instance需要volatile修饰,防止指令重排序导致的错误。

volatile除了保证线程缓存及时同步到主内存并清理其他线程缓存的值,还有一个作用就是防止指令重排序。 instance = new Singleton() 这行代码编译后会拆分成三个指令,可以理解成如下代码:

1,Singleton temp = malloc(); // 分配内存

2,constructor(temp); // 调用构造函数对分配的内存进行初始化

3,instance = temp; // 初始化完成的内存地址赋值给instance

编译器为了优化指令,重排序后,可能会变成了下面的代码:

1,Singleton temp = malloc(); // 分配内存

2,instance = temp; // 初始化完成的内存地址赋值给instance

3,constructor(instance); // 调用构造函数对分配的内存进行初始化

如果代码执行了上面的第二步,instance已经赋值不为null,但并没有初始化,这是如果第二个线程调用getInstance方法就会直接获得instance,调用instance时引发错误。volatile可以防止重排序。

四,通过内部类实现单例

public classSingleton{private static classSingletonHolder{private static Singleton instance = newSingleton();

}privateSingleton(){};private static volatile Singleton instance = null;public staticSingleton getInstance(){returnSingletonHolder.instance;

}

}

Singleton的实例被静态内部类SingletonHolder持有,只有在调用getInstance方法时,SingletonHolder才会被加载,instance被实例化。既实现懒加载,也不会有线程安全问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值