001
014
015 package com.liferay.portal.kernel.concurrent;
016
017 import java.util.Map;
018 import java.util.concurrent.ConcurrentHashMap;
019 import java.util.concurrent.locks.ReentrantLock;
020
021
024 public class LockRegistry {
025
026 public static ReentrantLock allocateLock(String groupName, String key) {
027 ConcurrentHashMap<String, ReentrantLock> lockGroup = _lockGroupMap.get(
028 groupName);
029
030 if (lockGroup == null) {
031 lockGroup = new ConcurrentHashMap<String, ReentrantLock>();
032
033 ConcurrentHashMap<String, ReentrantLock> oldLockGroup =
034 _lockGroupMap.putIfAbsent(groupName, lockGroup);
035
036 if (oldLockGroup != null) {
037 lockGroup = oldLockGroup;
038 }
039 }
040
041 ReentrantLock lock = lockGroup.get(key);
042
043 if (lock == null) {
044 lock = new ReentrantLock();
045
046 ReentrantLock oldLock = lockGroup.putIfAbsent(key, lock);
047
048 if (oldLock != null) {
049 lock = oldLock;
050 }
051 }
052
053 return lock;
054 }
055
056 public static ReentrantLock finallyFreeLock(
057 String groupName, String key, boolean unlock) {
058
059 if (_prematureLockReleases.containsKey(groupName + key)) {
060 return freeLock(groupName, key, unlock);
061 }
062
063 return null;
064 }
065
066 public static void freeAllLock() {
067 freeAllLock(false);
068 }
069
070 public static void freeAllLock(boolean unlock) {
071 if (unlock == true) {
072 for (Map<String, ReentrantLock> lockGroup :
073 _lockGroupMap.values()) {
074
075 for (ReentrantLock lock : lockGroup.values()) {
076 lock.unlock();
077 }
078 }
079 }
080
081 _lockGroupMap.clear();
082 _prematureLockReleases.clear();
083 }
084
085 public static Map<String, ReentrantLock> freeLock(String groupName) {
086 return freeLock(groupName, false);
087 }
088
089 public static Map<String, ReentrantLock> freeLock(
090 String groupName, boolean unlock) {
091
092 Map<String, ReentrantLock> lockGroup = _lockGroupMap.remove(groupName);
093
094 if (lockGroup == null) {
095 _prematureLockReleases.put(groupName, _dummyValue);
096
097 return null;
098 }
099
100 if (unlock == true) {
101 for (ReentrantLock lock : lockGroup.values()) {
102 lock.unlock();
103 }
104
105 _prematureLockReleases.remove(groupName);
106 }
107
108 return lockGroup;
109 }
110
111 public static ReentrantLock freeLock(String groupName, String key) {
112 return freeLock(groupName, key, false);
113 }
114
115 public static ReentrantLock freeLock(
116 String groupName, String key, boolean unlock) {
117
118 Map<String, ReentrantLock> lockGroup = _lockGroupMap.get(groupName);
119
120 String prematureLockReleasesKey = groupName + key;
121
122 if (lockGroup == null) {
123 _prematureLockReleases.put(prematureLockReleasesKey, _dummyValue);
124
125 return null;
126 }
127
128 ReentrantLock lock = lockGroup.remove(key);
129
130 if (lock == null) {
131 _prematureLockReleases.put(prematureLockReleasesKey, _dummyValue);
132
133 return null;
134 }
135
136 if (unlock) {
137 lock.unlock();
138
139 _prematureLockReleases.remove(prematureLockReleasesKey);
140 }
141
142 return lock;
143 }
144
145 public static ReentrantLock getLock(String groupName, String key) {
146 ConcurrentHashMap<String, ReentrantLock> lockGroup = _lockGroupMap.get(
147 groupName);
148
149 if (lockGroup == null) {
150 return null;
151 }
152
153 return lockGroup.get(key);
154 }
155
156 private static Object _dummyValue = new Object();
157 private static ConcurrentHashMap
158 <String, ConcurrentHashMap<String, ReentrantLock>>
159 _lockGroupMap =
160 new ConcurrentHashMap
161 <String, ConcurrentHashMap<String, ReentrantLock>>();
162 private static Map<String, Object> _prematureLockReleases =
163 new ConcurrentHashMap<String, Object>();
164
165 }