如何实现Singleton模式,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
设计一个类,我们只能生成该类的一个实例
私有构造方法
静态方法获取实例
如果需要考虑内存,使用到时才创建实例对象(饿汉),不使用时就不创建实例(懒汉,懒加载)。
如果需要考虑线程安全,就要确保获取实例是同步的,避免创建多个实例。
[x] 1. 单线程(懒汉式、饿汉式)
[x] 2. 多线程工作效率不高(加锁获取实例的方法)
[x] 3. 加同步锁前后两次判断实例是否已存在
[x] 4. 利用静态初始化创建实例(推荐,线程安全,会占用一部分内存)
[x] 5. 利用静态内部类实现按需创建实例(最推荐,线程安全,效率高,聪明的你应该可以明白的)
package cn.jast.java.offer.singleton;
/**
* 简单饿汉单例
*
*/
public class SimpleHungerSingleton {
private static SimpleHungerSingleton simpleSingleton;
private SimpleHungerSingleton(){
simpleSingleton = new SimpleHungerSingleton();
}
public static SimpleHungerSingleton getInstance(){
return simpleSingleton;
}
}
package cn.jast.java.offer.singleton;
/**
* 简单懒汉单例
*
*/
public class SimpleLazySingleton {
private static SimpleLazySingleton simpleSingleton;
private SimpleLazySingleton(){
}
public static SimpleLazySingleton getInstance(){
if(simpleSingleton == null){
simpleSingleton = new SimpleLazySingleton();
}
return simpleSingleton;
}
}
/**
* 测试简单单例的线程安全
*/
public static void testSimpleLazySingleton(){
Set<SimpleLazySingleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
SimpleLazySingleton simpleLazySingleton = SimpleLazySingleton.getInstance();
singletonSet.add(simpleLazySingleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
输出:
简单单例存在创建多个实例对象,实例如下:
[cn.jast.java.offer.singleton.SimpleLazySingleton@2b9283d, cn.jast.java.offer.singleton.SimpleLazySingleton@72fba635]
package cn.jast.java.offer.singleton;
public class Synchronized1Singleton {
private static Synchronized1Singleton instance;
private Synchronized1Singleton(){
}
/**
* 每次获取对象时都加锁来确保创建对象
* @return
*/
public static synchronized Synchronized1Singleton getInstance(){
if(instance == null){
instance = new Synchronized1Singleton();
}
return instance;
}
}
测试:
public static void testSynchronized1Singleton(){
long startTime = System.currentTimeMillis();
Set<Synchronized1Singleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
Synchronized1Singleton singleton = Synchronized1Singleton.getInstance();
singletonSet.add(singleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
System.out.println(String.format("执行时间:%s ms",System.currentTimeMillis()-startTime));
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
输出:
执行时间:72 ms(注:一个样例)
package cn.jast.java.offer.singleton;
public class Synchronized2Singleton {
private static Synchronized2Singleton instance;
private Synchronized2Singleton(){
}
public static Synchronized2Singleton getInstance(){
if(instance == null){
synchronized (Synchronized2Singleton.class){
if(instance==null){
instance = new Synchronized2Singleton();
}
}
}
return instance;
}
}
package cn.jast.java.offer.singleton;
/**
* 推荐
*/
public class StaticInitializeSingleton {
private static StaticInitializeSingleton instance ;
static{
instance = new StaticInitializeSingleton();
}
private StaticInitializeSingleton(){
}
public static StaticInitializeSingleton getInstance(){
return instance;
}
}
package cn.jast.java.offer.singleton;
/**
* 推荐
*/
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton(){
}
public static StaticInnerClassSingleton getInstance(){
return Inner.instance;
}
private static class Inner{
private static final StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
}
}
package cn.jast.java.offer.singleton;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
// testSimpleLazySingleton();
testSynchronized1Singleton();
// testSynchronized2Singleton();
// testStaticInitializeSingleton();
// testNestedClassSingleton();
}
/**
* 测试简单单例的线程安全
*/
public static void testSimpleLazySingleton(){
Set<SimpleLazySingleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
SimpleLazySingleton simpleLazySingleton = SimpleLazySingleton.getInstance();
singletonSet.add(simpleLazySingleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
/**
* 测试线程安全的单例模式实现
*/
public static void testSynchronized1Singleton(){
long startTime = System.currentTimeMillis();
Set<Synchronized1Singleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
Synchronized1Singleton singleton = Synchronized1Singleton.getInstance();
singletonSet.add(singleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
System.out.println(String.format("执行时间:%s ms",System.currentTimeMillis()-startTime));
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
/**
* Synchronized2Singleton 的效率比 Synchronized1Singleton高几倍甚至几十倍以上
*/
public static void testSynchronized2Singleton(){
long startTime = System.currentTimeMillis();
Set<Synchronized2Singleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
Synchronized2Singleton singleton = Synchronized2Singleton.getInstance();
singletonSet.add(singleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
System.out.println(String.format("执行时间:%s ms",System.currentTimeMillis()-startTime));
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
/**
*
*/
public static void testStaticInitializeSingleton(){
Set<Synchronized2Singleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
Synchronized2Singleton singleton = Synchronized2Singleton.getInstance();
singletonSet.add(singleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
public static void testNestedClassSingleton(){
Set<StaticInnerClassSingleton> singletonSet = Collections.synchronizedSet(new HashSet<>());
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 10; i++) {
executorService.submit(()->{
StaticInnerClassSingleton singleton = StaticInnerClassSingleton.getInstance();
singletonSet.add(singleton);
});
}
executorService.shutdown();
while(true){
if(executorService.isShutdown()){
if(singletonSet.size()>1){
System.out.println("简单单例存在创建多个实例对象,实例如下:");
System.out.println(singletonSet);
}
break;
}
}
}
}
问:单例模式获取实例的方法为什么是静态方法? 答:因为构造方法是私有的,无法通过new创建实例,那只能通过类方法获取实例。那通过反射是否可以创建实例呢?
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/jast90/blog/4560519