Tre*_*man 6 java string multithreading
是否有任何文件保证String.intern()是线程安全的?javadoc暗示它但不直接解决它:
返回字符串对象的规范表示.最初为空的字符串池由String类私有维护.
调用实习方法时,如果池已经包含等于此字符串对象的字符串(由equals(Object)方法确定),则返回池中的字符串.否则,将此String对象添加到池中,并返回对此String对象的引用.
因此,对于任何两个字符串s和t,当且仅当s.equals(t)为真时,s.intern()== t.intern()才为真.
所有文字字符串和字符串值常量表达式都是实体.字符串文字在The Java™Language Specification的3.10.5节中定义.
值得注意的是,javadoc说保证池中的String被返回,但不是池本身是线程安全的(因此写入它似乎会打开门,以便在竞争线程中更换池条目,虽然我认为这种解释不太可能).
和的JDK源String节目intern()是不揭示它的线程安全的灯光一个本地方法:
public native String intern();
Run Code Online (Sandbox Code Playgroud)
我关心的是具体涉及到是否以下将全部线程安全的,只有一个保证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
}
Run Code Online (Sandbox Code Playgroud)
我希望避免同步方法或缓存本身,因为对象的创建可能需要一些时间(需要网络访问).有一些解决方法,例如维护本地线程安全缓存/字符串池,但除非必要,否则不值得做.String.intern()(无法从缓存中删除内部字符串)的内存含义与此特定用例(使用少量字符串)无关.
我相信这String.intern()是线程安全的,上面的代码很好,但缺乏来自信誉良好的来源的直接确认让我有点担心.
此问题曾在此处多次提出,但未提供具体参考答案:
这实际上听起来像是您可能想要一个 Guava Striped<Lock>,它以散列方式将对象映射到锁。同步驻留字符串似乎是一种潜在危险的黑客行为,如果您使用的任何其他代码有相同的想法,则可能会产生奇怪的副作用。
| 归档时间: |
|
| 查看次数: |
1284 次 |
| 最近记录: |