Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standalone lock striping (e.g. map IDs to locks) #859

Closed
gissuebot opened this issue Oct 31, 2014 · 20 comments
Closed

Standalone lock striping (e.g. map IDs to locks) #859

gissuebot opened this issue Oct 31, 2014 · 20 comments

Comments

@gissuebot
Copy link

Original issue created by andr.maza on 2012-01-10 at 02:40 PM


The blog post here (http://illegalargumentexception.blogspot.com/2008/04/java-synchronizing-on-transient-id.html) describes a nice approach for synchronizing based on an ID.

I would like to request to enrich the current monitor with such a functionality.

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2012-01-10 at 03:41 PM


Could you describe your use case? Or do this yourself manually?

I'm a little wary of complicating the API further.

@gissuebot
Copy link
Author

gissuebot commented Oct 31, 2014

Original comment posted by nto...@maginatics.com on 2012-01-10 at 06:01 PM


Instead of extending the Monitor API, you could always maintain a Cache of all Monitors keyed off ID. You need to do some extra work to figure out the best way to evict unused monitors but that is a different topic.

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2012-01-11 at 12:14 AM


(No comment entered for this change.)


Status: WontFix
Labels: Type-Enhancement

@gissuebot
Copy link
Author

Original comment posted by andr.maza on 2012-01-11 at 12:29 PM


The use case is that I am performing several operations across different nosql datastores. Those operations are conducted based on a certain messageId. I want to prevent that the same set of operations runs concurrently for the same messageId.

Yes, this could be realized using a cache, which is quite similar to the approach described in the linked blog post. However, I would have been happy if such a feature becomes part of guava

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-12 at 04:55 AM


Well, internally we have Striped<Lock> (or Semaphore, or ReadWriteLock). Used like this:

Lock lock = stripedLock.get(ID);
Lock.lock();
...

There are multiple implementations of this:

  • one that preallocates a (given) number of stripes
  • and one that dynamically allocates stripes as needed, up to a given number, optionally holding them via weak references.

Operations accessing the same ID will get the same stripe. But, you control how much memory you want to spend on this, from "a single stripe/lock for all IDs", to "one stripe per each ID", e.g. you choose whatever memory consumption is enough to achieve sufficient concurrency.

A last nice feature is being able to get an Iterable<Lock> from Striped<Lock>.getAll(ID1, ID2, ...), which you can lock together without worrying about deadlocks.

Not sure when or if this ever escapes the internal labs code.

@gissuebot
Copy link
Author

Original comment posted by andr.maza on 2012-01-12 at 06:11 PM


Thanks for sharing that. It would be nice if this would make into guava.

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-13 at 08:19 AM


Kevin, why was this closed? Can we tentatively have it "accepted"? Also, any problem with just pasting the code here, for whoever wants to give it a spin?

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-13 at 08:24 AM


Title should change though, this is related to general lock striping, not Monitor in particular. (Btw, can you configure permissions for me so I can make changes like that? Thanks)

@gissuebot
Copy link
Author

gissuebot commented Oct 31, 2014

Original comment posted by nto...@maginatics.com on 2012-01-13 at 05:19 PM


Jim, independent of whether this makes it into Guava, it would be great to see (if possible, of course) how this particular lock striping solution works. Having implemented a solution myself, I am curious how you avoid deadlocks when you have multiple IDs mapped to one stripe/lock and you have to pick locks up as you go (vs. a getAll() call).

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-13 at 06:59 PM


(No comment entered for this change.)


Status: Accepted

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-13 at 07:28 PM


Got no replies, I guess it's no harm to just copy it here using the same guava license. Feedback welcome.

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2012-01-14 at 04:34 AM


Hmm... please consider my closing this bug to be accidental.

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2012-01-14 at 05:26 AM


I'm not that familiar with concurrency stuff, but might this play nicely with Monitor?

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-14 at 06:01 AM


Monitor is just a Lock where you don't need to manually signal() its Condition objects. It would work as much as with it does with Lock, but it would be really not worthwhile. Monitor is potentially useful only for code that uses Condition, and this is rare. Use cases for lock striping are also rare. The product of these two probabilities, the potential for Striped<Monitor>, would be really, really small.

For one, I was surprized to see Monitor in Guava, given its small niche. But its super elegant when applicable (kills a whole class of bugs around missed signals etc). The problem is, it's usually applicable in very low level code... where one would probably use lower level tools for performance.

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2012-01-20 at 12:05 AM


What obstacles are there to open-sourcing this? Waiting to see if it's adopted internally?

@gissuebot
Copy link
Author

Original comment posted by jim.andreou on 2012-01-20 at 01:28 AM


Not really waiting to be adopted internally. This is rather specialized and is supposed to have few usages. After half a year, it has about 10, and there were at least another 20 of users (at the time) that reinvent this (with constructs like Cache<..., Lock> -- I only count the easy ones to discover).

The real question would be if there was "enough" demand for it externally, to justify making guava a little bigger (otherwise, a user can just snatch the code locally).

That said, it definitely has more uses than Monitor. :) Which really got me by surprise when I saw it in guava (I think the author was surprised as well). Initially it managed to confuse some early readers of that, i.e. I learned its release by a blog that was focused entirely on Monitor, a couple of pages long, and yet it didn't have the word "signal" in it even once (which was the whole point!), so we had to update the javadocs right away. Btw, yay for MonitorExplained :)

(Hmm. There was something else that I was thinking earlier today that "oh this needs an -Explained page" but I can't remember right now. )

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2012-01-20 at 01:30 AM


Please let me know if you think a page is missing -- honestly, most of the stuff that's still left out is stuff I don't fully understand myself.

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2012-02-16 at 06:27 PM


(No comment entered for this change.)


Labels: Package-Concurrent

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2012-05-30 at 07:43 PM


(No comment entered for this change.)


Labels: -Type-Enhancement, Type-Addition

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2012-06-14 at 03:41 PM


Done, as of 61e6a48 .


Status: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant