简体   繁体   English

Java中是否存在基于生成的密钥的线程之间相互排斥的通用解决方案?

[英]Is there a generic solution in Java for mutual exclusion between threads based on a generated key?

Lets say I have a FooClass , which has an id with type long: 可以说我有一个FooClass ,其id为long类型:

public class FooClass {
    long id;
}

There is a method in whatever class with similar signature: 任何类中都有一个具有相似签名的方法:

public void shouldBeSynchronizedForAFooClassId(long fooClassId) {
    //does something
}

What could I do: 我能做什么:

  • I could make the method synchronized, but it is an unneccessary bottleneck, since FooClass with id 1 and FooClass with id 2 can run parallel without problem. 我可以使该方法同步,但它是一种不必要的瓶颈,由于FooClassid 1和FooClassid 2可以毫无问题平行地延伸。
  • I could generate a string with the id and make an intern() of it, and I could synchronize on that (I don't like this idea) 我可以生成一个带有id的字符串并对其进行intern(),并且可以对此进行同步(我不喜欢这个想法)
  • Synchronizing on Longs is also not a good idea. 在Longs上同步也不是一个好主意。
  • I could create a Map with id as key and a monitored Object as value. 我可以创建一个ID为键,被监视Object为值的Map This case I have to suffer with registering the number of threads using the same monitored Object to be able to cleanup the monitored Objects as soon as they are not used by any thread anymore. 在这种情况下,我必须使用相同的受监视对象注册线程数,以便一旦不再有任何线程使用被监视对象,便能够清除它们。

I thought, there must be a readymade solution like: 我认为,必须有一个现成的解决方案,例如:

  • There could be a LockManager or whatever, which is generized with a type (in my fall with Long above). 可能有一个LockManager或其他任何类型生成的类型(在我的秋天,上面是Long)。 It could provide a runSafely(Runnable run) method, which would do the mutual exclusion encapsulated, including generating the monitor object if needed, and removing it after. 它可以提供runSafely(Runnable run)方法,该方法将封装互斥对象,包括在需要时生成监视对象,然后将其删除。 Of course I have to get the id inside this runSafely as well. 当然,我也必须在runSafe内获取ID。

Is there something like this out of the box in some library? 在某些库中是否开箱即用?

您可以使用所需的工具,但必须自己组装解决方案,例如ReentrantLocks 的映射

There isn't, as far as I know, any ready-made solution to the problem you're facing in the JDK. 据我所知,没有任何现成的解决方案可以解决您在JDK中面临的问题。

But Guava has Striped , which does almost what you want. 但是番石榴具有Striped ,几乎可以满足您的需求。 It doesn't associate a lock per ID, but rather a lock per "stripe" of IDs. 它不关联每个ID的锁,而是关联ID的“条带”的锁。 That should be sufficient to avoid contention. 这应该足以避免争执。

Instead of long id , you could have ID id; 您可以使用ID id;代替long id ID id; where ID is a class that you define. ID是您定义的类。 Then you can simply lock the id object. 然后,您可以简单地锁定id对象。

Your ID class can have a numeric value, or whatever other attributes you find convenient. 您的ID类可以具有数值,也可以具有其他方便的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM