In our system, we have a method that will do some work when it\'s called with a certain ID:
public void doWork(long id) { /* ... */ }
Now, this
I might be late to the game, but this solution isn't leaking any memory and you don't have to remember to do any lock releases:
Synchronizer synchronizer = new Synchronizer();
...
// first thread - acquires "lock" for accountId accAAA
synchronizer.synchronizeOn(accountId("accAAA"), () -> {
long balance = loadBalance("accAAA")
if (balance > 10_000) {
decrementBalance("accAAA", 10_000)
}
})
...
// second thread - is blocked while first thread runs (as it uses the same "lock" for accountId accAAA)
synchronizer.synchronizeOn(accountId("accAAA"), () -> {
long balance = loadBalance("accAAA")
if (balance > 2_000) {
decrementBalance("accAAA", 2_000)
}
})
...
// third thread - won't be blocked by previous threads (as it is for a different accountId)
synchronizer.synchronizeOn(accountId("accXYZ"), () -> {
long balance = loadBalance("accXYZ")
if (balance > 3_500) {
decrementBalance("accXYZ", 3_500)
}
})
to use it you just add a dependency:
compile 'com.github.matejtymes:javafixes:1.3.0'