Last active
February 7, 2017 21:14
-
-
Save pathikrit/66e00295d88e44717786 to your computer and use it in GitHub Desktop.
Locking based on object equality rather than referential equality in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* An util that provides synchronization using value equality rather than referential equality | |
* It is guaranteed that if two objects are value-equal, their corresponding blocks are invoked mutually exclusively. | |
* But the converse may not be true i.e. if two objects are not value-equal, they may be invoked exclusively too | |
* Note: Typically, no need to create instances of this class. The default instance in the companion object can be safely reused | |
* | |
* @param size There is a 1/size probability that two invocations that could be invoked concurrently is invoked sequentially | |
* | |
* Example usage: | |
* import EquivalenceLock.{defaultInstance => lock} | |
* def run(person: Person) = lock(person) { .... } | |
*/ | |
class EquivalenceLock(val size: Int) { | |
private[this] val locks = IndexedSeq.fill(size)(new Object()) | |
def apply[A](lock: Any)(f: => A): A = locks(lock.hashCode().abs % size).synchronized(f) | |
} | |
object EquivalenceLock { | |
implicit val defaultInstance = new EquivalenceLock(1 << 10) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment