【问题标题】:Objective C equivalent of intern() in javaJava中intern()的Objective C等价物
【发布时间】:2023-03-03 13:13:01
【问题描述】:

我必须根据字符串实现一些同步算法。我的意思是两个线程必须同步,并且这对线程都依赖于一个字符串值(一对线程用于字符串 A,一对线程用于字符串 B,依此类推)。

在 java 中,我可以使用方法 intern 来实现算法,以获取两个线程共享的单个锁对象。 Java 将所有 litteral 提取到 jvm 内置池中,interne 允许将动态创建的任何字符串转换为池中的 litteral。

我明白there is also a pooling mechanism in Objective C

但是在 Java 中是否有任何与 intern() 等价的方法,即一种将普通字符串从字符串常量池转换为乱码字符串的方法。获取对这个唯一 String litteral 的引用,以便我的两个线程可以在同一个对象上同步。

我知道有一些解决方法,但它们都暗示了很多我想避免的字符串比较。 (虽然我相信实习生会这样做,但以一种优化的方式......)

用更一般的术语解释我的问题:我想避免使用将字符串映射到锁的字典。多亏了 intern,Java 允许我这样做,因为 String litteral (pooled) 将成为锁。有没有等效的或者我必须使用这张地图。

谢谢各位, 斯蒂芬

【问题讨论】:

  • 我认为在字符串文字上同步不是一个好主意。在字符串变量上可以,但在文字上,我不知道......但也许我错了。
  • 可能值得描述一下您的更高级别目标。一般来说,你想达到什么目的?您的问题听起来像是您已经为可能通过 Objective-C/Cocoa 中的其他方式更好地解决的问题制定了一个非常具体的解决方案。

标签: java objective-c string optimization synchronization


【解决方案1】:

我经常使用 Java 和 Objective-C 进行编程。

首先,您所描述的共享锁的方式似乎不太理想。这很棘手,也很脆弱,并且会使其他不太熟悉 String 实习的工作原理的程序员感到困惑。为什么不把一个类中的锁对象作为常量暴露给另一个类呢?

public class Foobar {

    public static final Object LOCK = new Object();

    public void doLockedStuff() {
        synchronized (LOCK) {
            // code here
        }
    }

}

public class Barfoo {
    public void doLockedStuff() {
        synchronized (Foobar.LOCK) {
            // code here
        }
    }
}

然后您可以在 Objective-C 中采用类似的方法 - 公开共享 LOCK 对象的类方法。

【讨论】:

  • 我相信任何好的解决方案,即使是困难的,只要有据可查,都是真正有效的。
  • 此方法与问题无关抱歉
  • 这确实与我认为使用实习字符串不利于在 Java 或 Objective-C 中锁定有关。相反,您应该使用专门为锁定而创建的共享对象。
【解决方案2】:

我认为将字符串映射到它们所代表的锁是你最好的选择。

您不想锁定 String 本身(或内部版本),因为它是 JVM 中的共享对象。你不知道 JVM 中的另一个组件是否也在做同样的事情,这可能会导致死锁。

Java Concurrency in Practice 更好地描述了这一点,但我目前找不到参考。

如果您使用 HashMap,包含您的锁的映射不会产生很大的性能问题,因为字符串是不可变的,并且字符串的哈希码可能只需要计算一次。

【讨论】:

    【解决方案3】:

    我终于使用了一个将每个字符串绑定到条件锁的字典。

    谢谢大家

    【讨论】:

      【解决方案4】:

      没有建议这是生成您正在寻找的锁的最佳方法,但这里有一个小技巧可以为您提供所需的效果:

      NSString *stringA = [NSString stringWithString:@"Hello"];
      NSString *stringB = [NSString stringWithFormat:@"%@l%@",@"Hel",@"o"];
      NSString *stringC = [NSString stringWithFormat:@"Hell%@", @"o"];
      
      NSLog(@"%p / %p / %p", stringA, stringB, stringC);
      
      NSNumber *lockA = [NSNumber numberWithUnsignedInteger:stringA.hash];
      NSNumber *lockB = [NSNumber numberWithUnsignedInteger:stringB.hash];
      NSNumber *lockC = [NSNumber numberWithUnsignedInteger:stringC.hash];
      
      NSLog(@"%p / %p / %p", lockA, lockB, lockC);
      

      您会注意到,尽管字符串具有不同的地址,但它们对应的 NSNumber 却没有。这是因为给定数字的 NSNumbers 是单例。

      您现在可以在这些“锁定”对象上使用@synchronize()

      -- 编辑--

      NSNumbers 是给定值的单例这一事实是实现的一个内部细节,这也是为什么购买真正的锁定机制(例如由 NSString 索引的字典)可能是一个好主意的原因之一。

      【讨论】:

      • 两个字符串可能具有相同的哈希
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 2022-12-08
      • 2011-07-21
      • 1970-01-01
      • 2021-08-09
      相关资源
      最近更新 更多