JVM字符串池线程是否为本地?它是否会导致此用例出现任何问题?

时间:2016-09-02 09:51:54

标签: java multithreading jvm thread-synchronization string-pool

互联网上的许多文章指出在多线程中使用String.intern()是不好的但我真的不明白为什么它是坏的。使用String.intern()始终从字符串池返回一个唯一的字符串,isn'是吗? 如果不是这样,那么 JVM字符串池线程是否是本地的?如果不是,那么为什么在多线程环境中使用String.intern()进行同步被认为是错误的?因此,在以下用例中,它不会解决同步问题:

Method1 {  
 synchronized(Interned string)  {  

  select method {  
   select query to databse  
  }  
  ...some processing...

  update method {  
   update query to database  
  }  
 }    
}

Method2 {  
 synchronized(Interned string)  {         
  select method {  
   select query to databse  
  }  
  .....some processing....

  insert method {  
   insert query to database  
  }  
 }       
}

这里我基于一个常见的字符串id同步这两个方法。我希望将整个方法作为一个事务执行(阻止其他方法甚至读取数据库)。但是在数据库级别执行此操作会导致死锁(不会阻止读取)访问)。在这种情况下使用字符串实习生进行同步是否有任何瓶颈或死锁问题?有没有其他方法可以解决这个问题? 请原谅我的任何不便或格式错误。

1 个答案:

答案 0 :(得分:1)

不,JVM中全局可以使用实习字符串。

正如this answer中所述:

  

同步实习生字符串实际上是一个非常糟糕的主意 - 部分原因是允许创建实习生字符串使其永久存在...

即。你可能会创造出越来越多的锁。

  

...部分是因为如果程序中任何地方的代码不止一位在实习字符串上同步,那么这些代码位之间就存在依赖关系,防止死锁或其他错误可能是不可能的。

字符串在整个JVM中都是可见的,因此任何地方的任何地方都可以尝试在同一个字符串上进行同步,从而导致难以重现,难以修复的问题。