JKeyLockManager
JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."
Abstract
The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.
...
manager.executeLocked("test1", new LockCallback() {
public void doInLock() {
...
}
});The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.
Behavior with concurrency
If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.
The methods of the KLM are reentrant and interruptible.
Example - web service with concurrency constraint
A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.
A simple solution with a global lock
public class WeatherServiceProxy {
...
public synchronized void updateWeatherData(String cityName, Date samplingTime, float temperature) {
delegate.updateWeatherData(cityName, samplingTime, temperature);
}
...Problem: The speedup is completely lost for compliance with the constraint. Concurrent access is even blocked for different city names. We need a finer grained lock.
Solution with KLM
public class WeatherServiceProxy {
...
private final KeyLockManager lockManager = KeyLockManagers.newManager();
public void updateWeatherData(String cityName, Date samplingTime, float temperature) {
lockManager.executeLocked(cityName, new LockCallback() {
public void doInLock() {
delegate.updateWeatherData(cityName, samplingTime, temperature);
}
});
}
...Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.
Getting started
Start with KeyLockManagers in order to get instances of KLM.