【问题标题】:Is JVM string pool thread local? Will it cause any issue with this use case? [duplicate]JVM 字符串池线程是本地的吗?它会导致这个用例出现任何问题吗? [复制]
【发布时间】:2016-09-02 09:51:54
【问题描述】:

互联网上的许多文章都指出在多线程中使用String.intern() 不好,但我真的不明白为什么它不好。使用String.intern() 总是从字符串池返回一个唯一的字符串,不是吗? 如果不是这种情况,那么 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 同步这两种方法。我想将整个方法作为一个事务执行(阻止其他方法甚至读取数据库)。但是在数据库级别执行此操作会导致死锁(不阻止读取使用权)。在这种情况下使用字符串实习生进行同步是否有任何瓶颈或死锁问题?有没有其他方法可以解决这个问题? 如有任何不便或格式错误,请见谅。

【问题讨论】:

  • 如果使用 String 进行同步还不够糟糕,你可以这样做:P vanilla-java.github.io/2016/04/21/Bad-String.html
  • 这显然是一个xy problem。你应该问问自己,一个全局数据库锁怎么会像正常情况下那样导致死锁,这是不可能的。死锁必须至少有两个锁,并且使用内部字符串作为锁对象不能修复软件中的逻辑错误。
  • 感谢您的回答,不便之处敬请谅解。我真的不知道 xy 问题,但正在向专家征求意见关于提出的解决方案和解决同一问题的不同方法不好?

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


【解决方案1】:

不,在 JVM 中可以全局使用内部字符串。

正如this answer中所说:

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

即您可能会创建越来越多的锁。

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

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

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 2017-06-28
    • 2012-08-21
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多