2

I want to synchronize a block of code, but do not want to simply lock on the implementing class (this).

The block of code in question is part of a method which takes in an id.

I want to disallow a new thread from entering the block if the id passed into the method is contained within a list in the class... if it not in the list, the entity is free to operate on, and thus the thread will be allowed into the block...

Is there a straight forward way to do this?

Gray
  • 115,027
  • 24
  • 293
  • 354
iammat
  • 61
  • 7
  • This might be the answer you're looking for:http://stackoverflow.com/a/17776425/1499922 – Erdem E. Mar 27 '17 at 17:58
  • 1
    What do you mean with “disallow”? `synchronized` will never disallow, it might only block until available, so what is your desired behavior? – Holger Mar 27 '17 at 18:07
  • 1
    why would you need `synchronization` in the first place? a simple check will not do, like `!if(list.contains(id)) return`? – Eugene Mar 27 '17 at 18:09
  • 1
    Guava has a nice [Striped](https://google.github.io/guava/releases/21.0/api/docs/com/google/common/util/concurrent/Striped.html) class for this sort of thing, so you don't need to roll your own. – Kayaman Mar 27 '17 at 18:22
  • 1
    @Eugene I especially like how the duplicate is itself a duplicate of a question that's closed as "not a real question". I'm wondering whether to reopen this. – Kayaman Mar 27 '17 at 18:24
  • 1
    @Eugene Yea, I had this same requirement a while ago, and I was trying to find an existing implementation in the JDK, but Striped is a very good shrink-wrapped solution to this. – Kayaman Mar 27 '17 at 18:27
  • 1
    For the record, this was closed as a duplicate of http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value – Kayaman Mar 27 '17 at 18:28

1 Answers1

5

There is no explicit class for this in the JDK, but as described in the (previous) duplicate, you can use ConcurrentHashMap to implement this kind of behaviour.

Guava provides the Striped class that gives you a good solution with plenty of configuration, such as lazily creating locks and weak locks, as well as configuring the amount of stripes (locks) to be used.

Community
  • 1
  • 1
Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • 1
    as promised, a one plus. – Eugene Mar 27 '17 at 18:34
  • 1
    Thanks. I'm not in it for the points though, I just wanted to include this so people won't think they need to roll their own solutions for things like this. I couldn't add this as an answer to the duplicate because...it's closed. – Kayaman Mar 27 '17 at 18:39
  • 1
    I know, up-vote was exactly for that. So that I would not make a fool of my-self showing a dumb solution. – Eugene Mar 27 '17 at 18:40
  • Striped locking is definitely the way to go. – bowmore Mar 27 '17 at 18:51
  • Well, the linked Q&A is from 2009, when you indeed had to built such a feature *atop* `ConcurrentHashMap`, but with Java 8, the `ConcurrentHashMap` *is* such a feature, i.e. `concurrentMap.compute(key, (k,v) -> { action; return v; }` performs `action` under a key specific lock. For a lot of cases, this is already sufficient. – Holger Mar 28 '17 at 09:56
  • @Holger True enough. However I also appreciate the clarity that you're working with locks, instead of a *collection* that involves locking although the end result is the same. – Kayaman Mar 28 '17 at 10:02