Objective C 相当于 java 中的 intern()

发布于 2024-12-03 19:13:45 字数 628 浏览 0 评论 0原文

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

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

我了解到还有一个池化机制目标C

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

我知道有一些解决方法,但它们都意味着我想避免大量的字符串比较。 (虽然我相信实习生会这样做,但以优化的方式......)

用更一般的术语解释我的问题:我想避免使用将字符串映射到锁的字典。 Java 允许我这样做,这要感谢实习生,因为字符串垃圾(池化)将成为锁。有没有等效的或者我必须使用这张地图。

谢谢各位, 史蒂芬

I got to implement some synchronization algorithms depending on strings. I mean two threads have to be synchronized and the pair of threads both depend on a string value (one pair of threads for String A, one pair for String B, and so on).

In java, I could implement the algorithm using the method intern to get a single lock object that is shared by both threads. Java pulls all litteral in a jvm built-in pool and interne allows to transform any string created dynamically into a litteral in the pool.

I understood that there is also a pooling mechanism in Objective C.

But is there any equivalent to intern() in Java, i.e a way to transform a normal String into a litteral String from the pool of String constants. To get the reference to this unique String litteral so that both my threads could get synchronize on the same object.

I know there are some work around but they all imply a lot of String comparisons that I would like to avoid. (Although I believe intern does it but in an optimized way...)

To explain my problem in more general term : I want to avoid having a Dictionnary that maps a String to a lock. Java allows me to do that thanks to intern as the String litteral (pooled) will become the lock. Is there any equivalent or must I use this map.

Thanks folks,
Stéphane

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一张白纸 2024-12-10 19:13:45

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

首先,您所描述的似乎是一种不太理想的共享锁方式。它很棘手,很脆弱,并且会让其他不熟悉字符串实习工作原理的编码人员感到困惑。为什么不在一个类中将一个锁对象作为常量暴露给另一个类呢?

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 对象的类方法。

I program regularly in both Java and Objective-C.

First, what you describe seems a less-than-ideal way to share a lock. It's tricky, it's brittle, and it will confuse other coders not so intimate with how String interning works. Why not just have a lock object in one class exposed to the other as a constant?

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
        }
    }
}

And then you can adopt a similar approach in Objective-C - a class method exposing a shared LOCK object.

〆一缕阳光ご 2024-12-10 19:13:45

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

您不想锁定 String 本身(或内部版本),因为它是 JVM 中的共享对象。您不知道 JVM 中的另一个组件是否正在执行相同的操作,这可能会导致死锁。

Java Concurrency in Practice 对此进行了更好的描述,但我目前找不到参考。

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

I think mapping the strings to the locks they represent is your best bet.

You don't want to lock on the String itself (or an interned version) because it's a shared object in the JVM. You don't know if another component in the JVM is doing the same thing, which could cause a deadlock.

Java Concurrency in Practice describes this better, but I can't find a reference at the moment.

The map containing your locks won't incur a large performance problem if you use a HashMap because Strings are immutable and the hash code of the String will likely only have to be calculated once.

坏尐絯 2024-12-10 19:13:45

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

谢谢大家

I finally used a dictionnary that binds every string to a conditionnal lock.

Thanks all

无妨# 2024-12-10 19:13:45

虽然没有暗示这是生成您正在寻找的锁的最佳方法,但这里有一个小技巧可以给您带来您想要的效果:

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 索引的字典)的原因之一例子。

Without suggesting that is the best way to generate the locks that you are looking for but here is a little hack to give you the effect you want:

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);

You will notice that eventhough the strings have different addresses, their corresponding NSNumbers don't. That's because NSNumbers for a given number is a singleton.

You can now use @synchronize() on these "lock" objects.

-- Edit --

The fact that NSNumbers are singletons for a given value is an internal detail to the implementation, which is one reason why it might be a good idea to shop around for a real locking mechanism such as a dictionary indexed by NSString for example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文