Skip to content

Instantly share code, notes, and snippets.

@pathikrit
Last active February 7, 2017 21:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pathikrit/66e00295d88e44717786 to your computer and use it in GitHub Desktop.
Save pathikrit/66e00295d88e44717786 to your computer and use it in GitHub Desktop.
Locking based on object equality rather than referential equality in Scala
/**
* 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