当前位置: 首页 > 面试题库 >

ExecutorService的线程安全静态初始化

薛祯
2023-03-14
问题内容

我试图基于初始化按需持有人习惯用法创建一个线程安全的单例类。这是我的代码

public class Check{ 
  private Check(){  }
  private static class Provider {
    static final ExecutorService INSTANCE = new ThreadPoolExecutor(5, "read this val from file", 60L, TimeUnit.SECONDS, new LinkedBlockingQueue());
  }
  public static ExecutorService getInstance() {
    return Provider.INSTANCE;
  }
}

我的期望是以线程安全的方式初始化ExecutorService,并且那里只有一个实例(静态)。

这段代码是实现了这一目标-还是需要任何更改?


问题答案:

根据SEI
指南,您的方法很好。

但是,由于我们有枚举,因此可以使用枚举的简单方法:

public enum Service {
  INSTANCE;

  private final ExecutorService service = ...
  public getService() { return service ; }

而且,如果您想变得真正聪明,还可以定义枚举实现的接口。因为这样您以后可以 模拟单例的用法。这对于使用相同线程执行服务替换编写单元测试非常有帮助。



 类似资料:
  • 问题内容: 我正在使用静态代码块来初始化我拥有的注册表中的某些控制器。因此,我的问题是,我可以保证在首次加载该类时,该静态代码块仅被绝对调用一次吗?我知道我不能保证何时将调用此代码块,我猜是在Classloader首次加载时。我意识到我可以在静态代码块中的类上进行同步,但是我猜这实际上是怎么回事? 简单的代码示例将是; 还是我应该这样做? 问题答案: 是的,Java静态初始化器是线程安全的(使用第

  • 假设我有一个Executors静态工厂方法的ExecutorService实例。 如果我从某个线程提交了一个调用,其中RetVal不是线程安全的本地实例化对象,那么当我从同一个线程获得()它时,我需要担心retvals的完整性吗?人们说局部变量是线程安全的,但我不确定当您返回一个本地实例化的对象并从其他线程接收它时,它是否适用。 下面是我的定制实现,我只是为了测试。您可以忽略EType枚举。

  • 问题内容: 假设我有一些Java代码: 如果一个线程正在初始化SomeClass的对象,并且在第二个线程想要再次加载SomeClass的过程中正在初始化静态块中的值,那么该静态块会怎样?即使第一个线程未完成,第二个线程是否仍假设它已初始化而忽略了它?还是发生其他事情? 问题答案: 如果第一个线程尚未完成对SomeClass的初始化,则第二个线程将阻塞。 Java语言规范的12.4.2节中对此进行了

  • 我的问题与静态变量的线程安全有关。 如果两个线程,t1具有静态锁,t2具有对象锁,可以同时继续,那么A类的状态测试将如何是线程安全的呢? 可能是,我错过了一些非常基本的东西,但不确定它是如何工作的。 根据下面的答案,我得到的印象是,如果必须使这些状态成为线程安全的,那么两个锁都应该由正在更新此状态的线程持有,或者确保它被仅静态方法或仅非静态方法访问。对吧?

  • 我有一个简单的静态日志记录类。但是,它肯定不是线程安全的,因为每个调用都试图写入同一个文件。我得到了这些例外情况: 什么是最好的方法使它的线程安全? 作为一个日志记录函数,我希望能够从代码的许多不同部分访问它(因此,我选择它为静态的原因)。然而,我想要使它成为线程安全的,我总是必须向它传递一个公共对象来lock(),我认为这违背了静态函数的目的。还是事实并非如此?

  • 问题内容: 如标题所示,两者之间到底有什么区别 和 除了结构以外,还有什么重要区别吗? 问题答案: 对于您的示例,没有区别。但是如您所见, 只能接受一个表达式来初始化变量。但是,在静态初始化器(JLS 8.7)中,可以执行任意数量的语句。例如,可以这样做: 对于您的示例,显然不需要这样做,但是变量的初始化可能不仅仅使用表达式,甚至可能包含许多语句,因此Java制作了静态初始化器。