我想在Java中使用String.intern()来节省内存(使用具有相同内容的字符串的内部池)。我从不同的线程调用这个方法。这是个问题吗?是String.intern()线程安全
回答
你的问题的简短答案是肯定的。它是线程安全的。
但是,您可能想重新考虑使用此功能来减少内存消耗。原因是你无法从实习字符串列表中删除任何实体。更好的解决方案是为此创建自己的设施。所有你需要的是你的字符串存储在一个HashMap<String,String>
像这样:
public String getInternedString(String s) {
synchronized(strings) {
String found = strings.get(s);
if(found == null) {
strings.put(s, s);
found = s;
}
return found;
}
}
(加上锁定,因为OP希望线程安全) – CodesInChaos 2013-02-10 13:15:46
你还可以提到可怕的'实习生'表现。如果我没有记错,时间复杂度为O(* n *),其中* n *是字符串池的当前大小。 – 2013-02-10 13:17:49
不应该是'if(found == null)'?而且,正如所写的,即使'strings'是一个线程安全的数据结构,这也不是线程安全的。 – 2013-02-10 19:37:58
由于返回一个不可变的Java字符串,该方法是线程安全的。您无法按原样操作字符串。
该文档确实暗示它是线程安全。 (通过强调任何)
由此可见任何两个字符串s和t,s.intern()== t.intern() 为真,当且仅当S .equals(t)是真的。
- 第三,JNI的接口使用的C语言
jobject
秒。jstring
就是其中之一,并且与定义一样,所有jobject
都是不可变的。因此,同样在本地c级别上,我们保留了线程安全性。
命名这些,我们有充足的理由说它是线程安全的。
PS:但是,如果您使用多个类加载器,则最终可能会产生具有挑战性的结果,因为字符串池按照String-class
来维护。
A pool of strings, initially empty, is maintained privately by the class String.
'java.lang.String'只能由引导类加载器加载。 – irreputable 2013-02-10 20:59:13
@irreputable我不知道你会怎么做,但如果有人这样做可能很重要。 – poitroae 2013-02-11 10:14:32
- 1. 部分线程安全是否使Java类线程安全?
- 2. 线程是否表示线程安全?
- 3. 是dispatch_semaphore_t线程安全
- 4. 是DatagramSocket.send线程安全吗?
- 5. 是TcpClient.Available线程安全吗?
- 6. 是否mysql_insert_id线程安全?
- 7. 是否log4j线程安全?
- 8. 线程安全(是吗?)
- 9. 是RSA_sign线程安全的
- 10. NSPasteboard是否线程安全?
- 11. 是unique_ptr线程安全吗?
- 12. 是System.DirectoryServices.AccountManagement.GroupPrincipal线程安全吗?
- 13. 是sqlite.swift线程安全吗?
- 14. 是AmazonSimpleNotificationServiceClient线程安全的?
- 15. 是res_query线程安全的?
- 16. 是DocumentBuilder.parse()线程安全吗?
- 17. 是Magento线程安全的?
- 18. 是Microsoft.Practices.EnterpriseLibrary.Data.Database.SetParameterValue线程安全吗?
- 19. 是长线程安全吗?
- 20. 是javax.sql.DataSource线程安全吗?
- 21. 是newKieSession线程安全的?
- 22. RegExp.MatchString是否线程安全?
- 23. 是java.util.UUID线程安全吗?
- 24. SeekableStream是否线程安全?
- 25. 查找安装的PHP是线程安全的还是非线程安全的?
- 26. 线程安全
- 27. 线程安全
- 28. 线程安全
- 29. 线程安全
- 30. 线程安全
如果不是线程安全,会感到非常惊讶。那是图书馆设计中的一个主要缺陷。 – CodesInChaos 2013-02-10 13:05:36
这些字符串从哪里来? – jlordo 2013-02-10 13:06:27
@jlordo - 任何不是编译时常量的字符串表达式都不会自动实现。因此,例如,'new String(“abc”)!=“abc”';但是,'“ab”+“c”==“abc”'(因为实习)。 – 2013-02-10 13:11:13