I have a multi-threaded application and I want to use re-entrant lock on a String
. For example if I use normal synchronization my code will look like.
I don't want two threads of same IPaddress to enter in my loadBalance()
so I take lock on IP address which is working fine.
class A {
String ipAddress;
...
void loadBalance() {
synchronized (ipAddress) {
// Business logic goes here
}
}
}
Now if I use Re-entrant API here then the code will look like below.Now two threads of same IP address is entering in my code which is not required. So I need to know how can I prevent this using Re-entrant API.
class A {
String ipAddress;
ReentrantLock lock = new ReentrantLock();
...
void loadBalance() {
lock.lock();
// Business logic goes here
lock.unlock();
}
}
My query is how could I take lock on IP address using Re-entrant
lock as I am doing in synchronized block
.
Rather than have a lock per
String
, which may lead to an ever growing amount of locks, and ultimately maybe anOutOfMemoryError
, it's better to use a striped locking strategy in this instance.Make a finite amount of locks (let's say
n
), store them in an array. If you need a lock for a givenString
use itshashCode()
and a modulon
to determine which array element contains the lock to use. EqualString
s will use the same lock.The trade off is that some non equal
String
s will use the same lock as well. You should test with varying amounts of n to strike a balance between unneeded lock contention and memory.Alternatively you could use Guava's
Striped
class