最近在做一个小型的单机项目。需要用到锁。为了增大并发。把ReentrantLock包装了一下。根据资源id。抢对应的锁。本人是菜鸟来的。希望大神指正。感谢。
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockUtil {
private volatile static HashMap<String, _ReentrantLock> moreReentrantLock = new HashMap<>();
// true公平锁
private static ReentrantLock lock = new ReentrantLock(true);
/**
* @param resource 资源id
* @param fair true 公平 false 非公平
* @param timeout 获取锁超时时间
* @param unit 时间单位
*/
public static synchronized boolean tryLock(String resource, boolean fair, long timeout, TimeUnit unit) throws InterruptedException {
if (StringUtils.isBlank(resource)) {
throw new NullPointerException("resource is null");
}
_ReentrantLock reentrantLock = moreReentrantLock.get(resource);
if (Objects.isNull(reentrantLock)) {
ReentrantLock newReentrantLock = new ReentrantLock(fair);
_ReentrantLock _reentrantLock_ = new _ReentrantLock(newReentrantLock, resource);
if (!moreReentrantLock.containsKey(resource)) {
moreReentrantLock.put(resource, _reentrantLock_);
}
// 如果为false 未取得锁 再尝试一次
if (!newReentrantLock.tryLock(timeout, unit)) {
return newReentrantLock.tryLock(2, unit);
}
return true;
} else {
if (!reentrantLock.getReentrantLock().tryLock(timeout, unit)) {
return reentrantLock.getReentrantLock().tryLock(2, unit);
}
return true;
}
}
public static synchronized void unLock(String resource) {
if (StringUtils.isBlank(resource)) {
return;
}
_ReentrantLock reentrantLock = moreReentrantLock.get(resource);
if (Objects.nonNull(reentrantLock)) {
ReentrantLock reentrantLock1 = reentrantLock.getReentrantLock();
// 当前线程才能unlock
if (reentrantLock1.isHeldByCurrentThread()) {
reentrantLock1.unlock();
moreReentrantLock.remove(resource);
}
}
}
static class _ReentrantLock {
private ReentrantLock reentrantLock;
private String resource;
public ReentrantLock getReentrantLock() {
return reentrantLock;
}
public void setReentrantLock(ReentrantLock reentrantLock) {
this.reentrantLock = reentrantLock;
}
public String getResource() {
return resource;
}
public void setResource(String resource) {
this.resource = resource;
}
public _ReentrantLock(ReentrantLock reentrantLock, String resource) {
this.reentrantLock = reentrantLock;
this.resource = resource;
}
// equals hashcode 进行重新 判断锁对象是否为同一个 使用resource 进行判断
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
_ReentrantLock that = (_ReentrantLock) o;
return resource.equals(that.resource);
}
@Override
public int hashCode() {
return Objects.hash(resource);
}
}
}