是否有任何书面证明String.intern()
的线程安全保证?javadoc暗示了它,但没有直接解决它:
返回字符串对象的规范表示。最初为空的字符串池由String类私有维护。
调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。
因此,对于任意两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()== t.intern()才为true。
所有文字字符串和字符串值常量表达式都将被插入。字符串文字在Java™语言规范的第3.10.5节中定义。
值得注意的是,javadoc表示可以保证返回池中的字符串,但不能保证池本身是线程安全的(因此,在编写时,它似乎为争用线程而替换池条目打开了大门。
,尽管我认为这种解释不太可能)。
和的JDK源String
节目intern()
是不揭示它的线程安全的灯光一个本地方法:
public native String intern();
我关心的是具体涉及到是否以下将全部线程安全的,保证只有一个MyObject
是 创建 (不只是存储在缓存中)在并发请求面对每个唯一的字符串值:
public void myMethod(String myString)
{
// Get object from cache, the cache itself is thread safe
MyObject object = myCache.get(myString);
if (object == null)
{
synchronized(myString.intern())
{
// Retry cache to avoid race condition
object = myCache.get(myString);
if (object == null)
{
object = new MyObject(myString);
// ... do some startup / config of the object ...
myCache.put(object);
}
}
}
// do something useful with the object
}
我希望避免在方法或缓存本身上进行同步,因为创建对象可能会花费一些时间(需要网络访问)。有一些变通办法,例如维护本地线程安全的高速缓存/字符串池,但是除非有必要,否则不值得这样做。String.intern()
(无法从缓存中删除插入的字符串)的内存含义与该特定用例(正在使用的字符串数量较少)无关。
我认为这String.intern()
是线程安全的,并且上面的代码还不错,但是缺乏可靠的消息来源的直接确认使我有些担心。
实际上,这听起来像您可能需要Guava Striped<Lock>
,它以散列方式将对象映射到锁。如果您正在使用的任何其他代码具有相同的想法,则对内联字符串进行同步似乎是一个潜在的危险黑客,它可能会产生怪异的副作用。
本文向大家介绍如何保证线程安全?相关面试题,主要包含被问及如何保证线程安全?时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程 通过合理的时间调度,避开共享资源的存取冲突。另外,在并行任务设计上可以通过适当的策略,保证任务与任务之间不存在共享资源,设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成,而不是把一个客户的计算工作分配给多个线程去完成。
本文向大家介绍java枚举是如何保证线程安全的,包括了java枚举是如何保证线程安全的的使用技巧和注意事项,需要的朋友参考一下 前言 写在前面:Java SE5提供了一种新的类型-Java的枚举类型,关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能。本文将深入分析枚举的源码,看一看枚举是怎么实现的,他是如何保证线程安全的
volatile的写操作,无法保证线程安全。例如假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值,在线程1对count进行修改之后,会write到主内存中,主内存中的count变量就会变为6;线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6;导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。
本文向大家介绍在 Java 程序中怎么保证多线程的运行安全?相关面试题,主要包含被问及在 Java 程序中怎么保证多线程的运行安全?时的应答技巧和注意事项,需要的朋友参考一下 方法一:使用安全类,比如 Java. util. concurrent 下的类。 方法二:使用自动锁 synchronized。 方法三:使用手动锁 Lock。 手动锁 Java 示例代码如下:
问题内容: 一个共同的(1,2)实现单的方式是使用具有静态构件的内部类: 据说此实现是延迟初始化的,并且是线程安全的。但是到底什么能保证其线程安全呢?处理 线程和锁的 JLS 17 并未提及静态字段具有任何类型的 事前发生 关系。如何确定初始化仅发生一次并且所有线程都看到相同的实例? 问题答案: 我们首先需要了解两点: 加载类时,静态初始化 仅 发生 一次 在声明中具有static修饰符的 字段
问题内容: 好吧,考虑下面给出的不可变类: 现在,我正在一个类中创建一个对象,该对象的对象将由多个线程共享: 看到as 并移入同步块并创建对象。现在,由于 Java内存模型(JMM)允许多个线程在初始化开始之后但尚未结束之前观察对象。 因此,可以将写入操作视为在写入的字段之前发生。因此,因此可以看到部分构造,该构造很可能处于无效状态,并且其状态以后可能会意外更改。 它不是非线程安全的吗? 编辑 好