
org.bonitasoft.engine.lock.impl.MemoryLockService Maven / Gradle / Ivy
/**
* Copyright (C) 2012 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.bonitasoft.engine.lock.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.bonitasoft.engine.lock.LockService;
import org.bonitasoft.engine.lock.SLockException;
import org.bonitasoft.engine.log.technical.TechnicalLogSeverity;
import org.bonitasoft.engine.log.technical.TechnicalLoggerService;
/**
* This service must be configured as a singleton.
*
* @author Elias Ricken de Medeiros
*/
public class MemoryLockService implements LockService {
private static final String SEPARATOR = "_";
private static final Object lock = new Object();
private final TechnicalLoggerService logger;
private final boolean debugEnabled;
public MemoryLockService(final TechnicalLoggerService logger) {
this.logger = logger;
debugEnabled = logger.isLoggable(MemoryLockService.class, TechnicalLogSeverity.DEBUG);
}
private final Map readWriteLock = new HashMap();
private final Map lockCount = new HashMap();
private void ensureProcessHasLockObject(final String key) {
synchronized (lock) {
long updatedLockCount;
if (!readWriteLock.containsKey(key)) {
// use fair mode?
readWriteLock.put(key, new ReentrantReadWriteLock());
updatedLockCount = 0L;
} else {
updatedLockCount = lockCount.get(key);
}
lockCount.put(key, updatedLockCount + 1);
}
}
@Override
public void createExclusiveLockAccess(final long objectToLockId, final String objectType) throws SLockException {
if (debugEnabled) {
logger.log(MemoryLockService.class, TechnicalLogSeverity.DEBUG, "[LOCK]request X id=" + objectToLockId + ", type=" + objectType);
}
final String key = getKey(objectToLockId, objectType);
ensureProcessHasLockObject(key);
readWriteLock.get(key).writeLock().lock();
if (debugEnabled) {
logger.log(MemoryLockService.class, TechnicalLogSeverity.DEBUG, "[LOCK]acquired X id=" + objectToLockId + ", type=" + objectType);
}
}
private String getKey(final long objectToLockId, final String objectType) throws SLockException {
final StringBuilder stb = new StringBuilder();
stb.append(objectType);
stb.append(SEPARATOR);
stb.append(objectToLockId);
return stb.toString();
}
@Override
public void releaseExclusiveLockAccess(final long objectToLockId, final String objectType) throws SLockException {
if (debugEnabled) {
logger.log(MemoryLockService.class, TechnicalLogSeverity.DEBUG, "[LOCK]release X id=" + objectToLockId + ", type=" + objectType);
}
final String key = getKey(objectToLockId, objectType);
readWriteLock.get(key).writeLock().unlock();
removeFromMapIfPossible(key);
}
@Override
public void createSharedLockAccess(final long objectToLockId, final String objectType) throws SLockException {
if (debugEnabled) {
logger.log(MemoryLockService.class, TechnicalLogSeverity.DEBUG, "[LOCK]request S id=" + objectToLockId + ", type=" + objectType);
}
final String key = getKey(objectToLockId, objectType);
ensureProcessHasLockObject(key);
readWriteLock.get(key).readLock().lock();
if (debugEnabled) {
logger.log(MemoryLockService.class, TechnicalLogSeverity.DEBUG, "[LOCK]acquired S id=" + objectToLockId + ", type=" + objectType);
}
}
@Override
public void releaseSharedLockAccess(final long objectToLockId, final String objectType) throws SLockException {
if (debugEnabled) {
logger.log(MemoryLockService.class, TechnicalLogSeverity.DEBUG, "[LOCK]release S id=" + objectToLockId + ", type=" + objectType);
}
final String key = getKey(objectToLockId, objectType);
readWriteLock.get(key).readLock().unlock();
removeFromMapIfPossible(key);
}
private void removeFromMapIfPossible(final String key) {
synchronized (lock) {
if (lockCount.containsKey(key)) {
final Long count = lockCount.get(key) - 1;
lockCount.put(key, count);
if (count <= 0) {
readWriteLock.remove(key);
lockCount.remove(key);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy