Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.concurrent.Semaphore;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.log4j.Logger;
- public class LockManager {
- private static LockManager instance;
- private HashMap<String, Semaphore> map = new HashMap<String, Semaphore>();
- private static final String KEY_DELIMITER = "#";
- private static final Pattern PATTERN = Pattern.compile("(.+?)" + KEY_DELIMITER);
- private Logger logger = Logger.getLogger(LockManager.class);
- private LockManager() {
- }
- public static LockManager getInstance() {
- if (instance == null) {
- synchronized (LockManager.class) {
- // Método "double-check idiom" utilizado para sincronizar apenas
- // na primeira chamada do getInstance();
- if (instance == null) {
- instance = new LockManager();
- }
- }
- }
- return instance;
- }
- public String generateKey(String key1, String key2) {
- return (key1 + KEY_DELIMITER + key2);
- }
- public void acquire(String key1, String key2) throws InterruptedException {
- String key = generateKey(key1, key2);
- acquire(key);
- }
- /*
- * Método responsável por instanciar e/ou adquirir o mutex/lock de acordo o
- * atributo key ps: Controle de concorrência por key, ou seja, cada key será
- * relacionada a apenas 1 mutex obrigatoriamente
- */
- public void acquire(String key) throws InterruptedException {
- Semaphore mutex = null;
- // Sincroniza o map de modo que threads relacionadas à mesma key não
- // insira dois registros no map
- synchronized (map) {
- mutex = map.get(key);
- if (mutex == null) {
- mutex = new Semaphore(1);
- map.put(key, mutex);
- }
- }
- // obtem o lock para o atributo key
- mutex.acquire();
- }
- public void release(String key1, String key2) {
- String key = generateKey(key1, key2);
- release(key);
- }
- /*
- * Método responsável por liberar o mutex de acordo com o atributo key
- * passado como parâmetro ps: O release deve ser sempre efetuado em algum
- * momento após a obtenção do lock. Caso contrário threads relacionadas à
- * mesma chave ficarão bloqueadas
- */
- public void release(String key) {
- Semaphore mutex = map.get(key);
- if (mutex != null) {
- mutex.release();
- }
- }
- public void removeFinally(String pin) {
- if (map != null) {
- synchronized (map) {
- logger.info("Tamanho atual da estrutura de dados map: " + map.size());
- Iterator<String> keySet = map.keySet().iterator();
- logger.info("Inicio da tentativa de limpeza do map para a ordem: " + pin);
- while (keySet.hasNext()) {
- String key = keySet.next();
- String mapPin = getPinFromKey(key);
- try {
- if (mapPin.equals(pin)) {
- // Obtém o mutex com base na key e o libera, caso o
- // mesmo esteja bloqueado.
- Semaphore mutex = map.get(key);
- mutex.release();
- // remove a key do map
- keySet.remove();
- }
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
- }
- }
- }
- }
- public String getPinFromKey(String key) {
- String pin = "";
- Matcher matcher = PATTERN.matcher(key);
- if (matcher.find()) {
- pin = matcher.group(1);
- }
- return pin;
- }
- /**
- * Faz a limpeza da variável de instância "map" declarada na classe
- * LockManager.
- */
- public class ClearMap implements Runnable {
- private boolean keepAlive = true;
- private long sleepTime = 1800000;
- @Override
- public void run() {
- try {
- while (keepAlive) {
- Thread.sleep(sleepTime);
- synchronized (map) {
- logger.info("Limpando o mapa de sincronização de sessões. Tamanho atual: " + map.size());
- map.clear();
- }
- }
- } catch (InterruptedException e) {
- logger.error(e.getMessage(), e);
- }
- }
- public void setKeepAlive(boolean _keepAlive) {
- this.keepAlive = _keepAlive;
- }
- public void setSleepTime(long _sleepTime) {
- this.sleepTime = _sleepTime;
- }
- }
- }
Add Comment
Please, Sign In to add comment