您可以使用Optional在Java 8+中实现Singleton模式吗?>

问题描述 投票:-2回答:1

因此,典型的Singleton模式如下所示:

public class SampleObject {
  private static SampleObject sampleObject = null;

  private SampleObject() {}

  public static SampleObject getInstance() {
    if (sampleObject == null) sampleObject = new SampleObject();
    return sampleObject;
  }
}

我尝试使用Optional这样编写getInstance()函数:

public static SampleObject getInstance() {
    sampleObject = Optional.ofNullable(sampleObject).orElse(new SampleObject());
    return sampleObject;
  }

出于某种奇怪的原因,它适用于某些类,而对于某些类却无效。

我实现错误吗?还是无法使用Optional实现Singleton模式?

****编辑***当我运行这段代码]

import java.util.*;

class ObjTracker {
  private static ObjTracker objTracker;

  private ObjTracker() {}

  public static ObjTracker getInstance() {
    objTracker = Optional.ofNullable(objTracker).orElse(new ObjTracker());
    return objTracker;
  }
}

class Main {

  public static void main(String[] args) {
    var objTracker = ObjTracker.getInstance();
    var objTracker1 = ObjTracker.getInstance();
    System.out.println(objTracker);
    System.out.println(objTracker1);
  }
}

objTracker和objTracker1都等于ObjTracker的相同实例,因此orElse并不总是得到执行。

因此,典型的Singleton模式如下所示:public class SampleObject {private static SampleObject sampleObject = null;私人SampleObject(){}公共静态SampleObject getInstance(...)>>

在Java中实现单例模式的最佳方法是通过Classloader,我知道至少有三种好的方法:

a)渴望初始化

class EagerSingleton{

    private EagerSingleton(){}
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    public static EagerSingelton getInstance(){
        return INSTANCE;
    }

}

b)使用内部Holder类的惰性初始化

class LazySingleton{
    private LazySingleton(){}
    public static LazySingleton getInstance(){
        return Holder.INSTANCE;
    }

    private static class Holder{
        // this field only gets initialized after getInstance()
        // is called for the first time
        private static final LazySingleton INSTANCE = new LazySingleton();
    }

}

c)枚举

enum EnumSingleton{
    INSTANCE;
}

根据您的使用情况选择其中之一。

虽然我喜欢您使用Optional的想法,但如果一个线程要请求单例而另一个线程要创建单例,则会导致争用情况。只有Classloader才能保证只能创建一个对象。

java design-patterns singleton optional
1个回答
0
投票

在Java中实现单例模式的最佳方法是通过Classloader,我知道至少有三种好的方法:

© www.soinside.com 2019 - 2024. All rights reserved.