Reputation: 103
I'm using Stripe.lock()
from com.google.guava.guava-28.0-jre.jar
public class NamedLock {
private static final Logger LOGGER = Logger.getLogger(NamedLock.class);
private Striped<Lock> locks;
public NamedLock() {
locks = Striped.lock(1023);
}
/**
* Test method
*
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
NamedLock namedLock = new NamedLock();
Runnable runnable = () -> {
namedLock.lock("aAp1h0000004oEcCAI");
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
namedLock.lock("aAT1h0000001OzCGAU");
};
new Thread(runnable).start();
TimeUnit.SECONDS.sleep(2);
namedLock.lock("aAp1h0000004oFRCAY");
namedLock.lock("aAp1h0000004oKYCAY");
}
/**
* Acquires the lock for the Names.
*
* @param names
* the Names
*/
public void lock(String... names) {
String key = Arrays.toString(names);
LOGGER.debug("Locking with Key : " + key);
Lock lock = locks.get(key);
LOGGER.debug("Acquiring Lock : " + lock);
lock.lock();
LOGGER.debug("Lock acquired : " + lock);
}
/**
* Releases the lock acquired for the Names.
*
* @param names
* the Names
*/
public void unlock(String... names) {
String key = Arrays.toString(names);
LOGGER.debug("Unlocking with Key : " + key);
Lock lock = locks.get(key);
LOGGER.debug("Releasing Lock : " + lock);
lock.unlock();
LOGGER.debug("Lock released : " + lock);
}
}
Result for the program :
| DEBUG | 2019-08-13 14:58:33.973 | Thread-0 | NamedLock:61 | Locking with Key : [aAp1h0000004oEcCAI]
| DEBUG | 2019-08-13 14:58:33.975 | Thread-0 | NamedLock:63 | Acquiring Lock : com.google.common.util.concurrent.Striped$PaddedLock@ac92ce3[Unlocked]
| DEBUG | 2019-08-13 14:58:33.975 | Thread-0 | NamedLock:65 | Lock acquired : com.google.common.util.concurrent.Striped$PaddedLock@ac92ce3[Locked by thread Thread-0]
| DEBUG | 2019-08-13 14:58:35.973 | main | NamedLock:61 | Locking with Key : [aAp1h0000004oFRCAY]
| DEBUG | 2019-08-13 14:58:35.974 | main | NamedLock:63 | Acquiring Lock : com.google.common.util.concurrent.Striped$PaddedLock@574caa3f[Unlocked]
| DEBUG | 2019-08-13 14:58:35.980 | main | NamedLock:65 | Lock acquired : com.google.common.util.concurrent.Striped$PaddedLock@574caa3f[Locked by thread main]
| DEBUG | 2019-08-13 14:58:35.981 | main | NamedLock:61 | Locking with Key : [aAp1h0000004oKYCAY]
| DEBUG | 2019-08-13 14:58:35.982 | main | NamedLock:63 | Acquiring Lock : com.google.common.util.concurrent.Striped$PaddedLock@ac92ce3[Locked by thread Thread-0]
| DEBUG | 2019-08-13 14:58:38.976 | Thread-0 | NamedLock:61 | Locking with Key : [aAT1h0000001OzCGAU]
| DEBUG | 2019-08-13 14:58:38.982 | Thread-0 | NamedLock:63 | Acquiring Lock : com.google.common.util.concurrent.Striped$PaddedLock@574caa3f[Locked by thread main]
The program never terminates and goes into DeadLock state, waiting for each others lock though all the keys are different.
Upvotes: 1
Views: 522
Reputation: 44200
From the JavaDoc:
Note that if key1 is not equal to key2, it is not guaranteed that
striped.get(key1) != striped.get(key2)
So presumably more than one of your keys exists in the same stripe. The hash codes are relatively close together for some of them so it seems reasonable:
System.out.println("[aAp1h0000004oEcCAI]".hashCode()); // -1286359401
System.out.println("[aAp1h0000004oFRCAY]".hashCode()); // -1273429611
System.out.println("[aAp1h0000004oKYCAY]".hashCode()); // -1123819209
System.out.println("[aAT1h0000001OzCGAU]".hashCode()); // 1694776185
It sounds like Striped is not applicable to your use-case and that you need one lock per object.
Upvotes: 2