【问题标题】:Creating an object from string and using as monitor in synchronized block [duplicate]从字符串创建对象并在同步块中用作监视器[重复]
【发布时间】:2021-04-19 21:27:10
【问题描述】:

我在某些类上使用了注解,通过反射,我得到了该注解的一些字符串,每个类都是唯一的。

我正在考虑使用该字符串来同步代码块,但我只想在注释字符串值相同的情况下阻止对代码的访问,如果字符串不同,则另一个线程可以进入执行其任务。我知道我不能直接使用字符串并且整数没有监视器,所以我不能直接使用哈希码。当我使用 jMeter 加载测试这段代码时,这种方式是否会产生任何问题。

public class LockObject {

   private String lockString;

   public LockObject(String lockString) {
       this.lockString = lockString;
   }

   public int hashCode() {
       returns hashcode for string;
   }

   @Override
   public boolean equals(Object obj) {
   }
}

public class TestClass {

   public void someMethod() {
       String annotationString = "fetchedByAnnotation that i use on some class by reflection";
       //what i want if string is same then second thread won't enter this block
       synchronized (new LockObject(annotationString)) {
           //some task based on that string
       }
   }
}

【问题讨论】:

    标签: java multithreading parallel-processing synchronized java-threads


    【解决方案1】:

    我知道我不能直接使用字符串并且整数没有监视器所以 我不能直接使用哈希码。

    是的,尽管如此,您可以(但您不应该)利用intern() 方法。来自source 可以阅读:

    java字符串intern()方法返回interned字符串。它 返回字符串的规范表示。

    如果它是由new创建的,它可以用来从内存中返回字符串 关键词。它在字符串中创建堆字符串对象的精确副本 常量池。

    String annotationString = // ...;
    synchronized (annotationString.intern())
    

    尽管如此,锁定字符串的问题是其他对象可能会出于完全不同的目的无意中锁定相同的字符串。换句话说,字符串具有全局语义范围,您无法控制确保这些相同的字符串不会在其他地方用作锁定机制。从此SO Thread(除其他外)可以阅读:

    不鼓励锁定字符串,主要原因是(因为 string-interning) 一些其他代码可以锁定在同一个字符串上 例如,您不知道这一点。造成死锁的可能性 情况。

    现在这在最具体的情况下可能是一个牵强的场景 情况。这更像是图书馆的一般规则。

    另一种解决方案是使用<String, Object> 中的Map,其中key 是从注释中读取的字符串,value 是线程可用于同步的对象。

    Map 将在线程之间共享,因此在访问这样的Map 时必须确保mutual exclusion。每次线程从注释中读取字符串时,如果尚未添加,则将该字符串添加到 Map,否则在与该字符串 key 关联的 value 上同步。

    【讨论】:

    • 我会看看条纹锁。所以只是一个锁对象数组,并使用字符串的哈希来确定锁索引。
    • @pveentjer 是的,我同意,它直截了当,还有一个更复杂的锁定机制的额外好处,尽管也稍微复杂一些。
    猜你喜欢
    • 2015-07-13
    • 2014-12-23
    • 2018-08-11
    • 2019-05-20
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多