同步相同的字符串值

jas*_*man 7 java synchronization

假设我有一个为Web应用程序创建新用户的方法.该方法本身调用一个静态助手类,该类创建一个SQL语句,用于执行实际插入到我的数据库中.

public void createUserInDb(String userName){
    SQLHelper.insertUser(userName);
}
Run Code Online (Sandbox Code Playgroud)

我希望同步此方法,以便如果传入的参数(userName)在这些线程上相同,则不能由不同的线程同时调用它.我知道我可以使用synchronized关键字同步方法执行,但这会阻止不同的线程同时执行该方法.如果传入的变量相同,我只想防止并发执行.Java中有一个简单的构造可以让我这样做吗?

Mur*_*nik 6

无法保证具有相同值的两个字符串将指向Java中的同一实例,尤其是如果它们是从用户输入创建的.

但是,您可以使用该intern()方法轻松地将它们强制进入字符串池,这将保证它与使用的实例相同:

public void createUserInDb(String userName){
    String interned = userName.intern();
    synchronized (interned) {
        SQLHelper.insertUser(interned);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Jesper多年来,这种情况并非如此.Interned字符串可以像其他字符串一样进行垃圾收集.请参阅[此答案](http://stackoverflow.com/a/18153570/207421)以及我对[this one](http://stackoverflow.com/a/2431597/207421)的评论,大幅上调. (3认同)
  • 但是,像这样的内部字符串并不是一个好主意。这可能会导致内存泄漏-驻留在字符串池中的字符串会一直保留在那里,直到JVM退出为止。 (2认同)
  • @EJP String.intern()的行为取决于JVM版本。对于JVM 6,7,8,“ String.intern”的行为有很大不同,例如,请参见[Mikhail Vorontsov-Java 6、7和8中的String.intern –字符串池]的博客(http:// java- performance.info/string-intern-in-java-6-7-8/)。有关更多详细信息,请访问http://bugs.sun.com/view_bug.do?bug_id=6962931和http://bugs.sun.com/view_bug.do?bug_id=6962930。 (2认同)