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

如何使静态日历线程安全

卢恩
2023-03-14
问题内容

我想将Calendar用于某些静态方法并使用一个静态字段:

private static Calendar calendar = Calendar.getInstance();

现在,我读到java.util.Calendar不是线程安全的。如何使该线程安全(应该是 静态的 )?


问题答案:

如果不是,则不能创建线程安全的东西。在的情况下Calendar,即使从中 读取 数据也不是线程安全的,因为它可以更新内部数据结构。

如果有可能,我建议改用Joda Time:

  • 大多数类型是不可变的
  • 不可变类型是线程安全的
  • 无论如何,这通常是一个更好的API

如果绝对 必须 使用Calendar,则可以创建一个锁定对象,并通过一个锁放置所有访问权限。例如:

private static final Calendar calendar = Calendar.getInstance();
private static final Object calendarLock = new Object();

public static int getYear()
{
    synchronized(calendarLock)
    {
        return calendar.get(Calendar.YEAR);
    }
}

// Ditto for other methods

虽然很讨厌。当然,您可能只有 一个
同步方法,该方法每次需要时都会创建原始日历的副本,当然……有可能通过调用computeFields或者computeTime您可以使 后续的
读取操作成为线程安全的,当然,但是我个人而言d讨厌尝试。



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

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

  • 问题内容: 是否可以通过任何常规方法或规则来确保专门用于任何应用程序的各种Utility类的静态方法的线程安全性。在这里,我想特别指出Web应用程序的线程安全性。 众所周知,以不可变对象作为参数的静态方法是线程安全的,而可变对象不是。 如果我有一个实用程序方法可用于的某些操作,并且该方法接受的实例,则该方法将不是线程安全的。那么如何在不更改参数传递方式的情况下使其成为线程安全的呢? 课堂也是可变的

  • 问题内容: 我试图基于初始化按需持有人习惯用法创建一个线程安全的单例类。这是我的代码 我的期望是以线程安全的方式初始化ExecutorService,并且那里只有一个实例(静态)。 这段代码是实现了这一目标-还是需要任何更改? 问题答案: 根据SEI 指南,您的方法很好。 但是,由于我们有枚举,因此可以使用枚举的简单方法: 而且,如果您想变得真正聪明,还可以定义枚举实现的接口。因为这样您以后可以

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

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