116 lines
3.0 KiB
Java
116 lines
3.0 KiB
Java
package util;
|
|
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
|
|
public class Lockeys {
|
|
|
|
private static Lockeys lockeys = new Lockeys();
|
|
|
|
private final ThreadLocal<Map<Lockey, LockeyHolder> >locks =new ThreadLocal<>(); ;
|
|
|
|
public static Lockeys getLockeys() {
|
|
return lockeys;
|
|
}
|
|
private Lockeys() {
|
|
}
|
|
private static Lockeys instance = new Lockeys();
|
|
public static Lockeys getInstance(){
|
|
return instance;
|
|
}
|
|
|
|
private Entry[] table = new Entry[1 << 10]; //默认给1024 省去扩容
|
|
|
|
static class Entry extends WeakReference<Lockey> {
|
|
private Entry next;
|
|
|
|
Entry(Lockey k, Entry v) {
|
|
super(k);
|
|
this.next = v;
|
|
}
|
|
}
|
|
|
|
Lockey getLockey(Object object, int id) {
|
|
return get(new Lockey(id, object));
|
|
}
|
|
|
|
public synchronized Lockey get(Lockey lockey) {
|
|
|
|
Map<Lockey, LockeyHolder> lockeyLockeyHolderMap = locks.get();
|
|
if(lockeyLockeyHolderMap==null){
|
|
lockeyLockeyHolderMap= new HashMap<>();
|
|
locks.set(lockeyLockeyHolderMap);
|
|
}
|
|
LockeyHolder holder = locks.get().get(lockey);
|
|
if (holder != null)
|
|
return holder.lockey;
|
|
int h = lockey.hashCode();
|
|
Entry e = table[h & (1 << 10 - 1)];
|
|
if (e == null) {
|
|
e = new Entry(null, null);
|
|
table[h & (1 << 10 - 1)] = e;//to fix 漏写了 查半天
|
|
}
|
|
|
|
while (e.next != null) {
|
|
Lockey _key = e.next.get();
|
|
if (_key == null)
|
|
e.next = e.next.next;
|
|
else if (_key.equals(lockey))
|
|
return _key;
|
|
else
|
|
e = e.next;
|
|
}
|
|
e.next = new Entry(lockey, null);
|
|
return lockey.alloc();
|
|
}
|
|
|
|
|
|
public void lock(String key, Integer index) {
|
|
Lockey lockey = getLockey(key, index);
|
|
LockeyHolder holder = this.locks.get().get(lockey);
|
|
if (holder == null) {
|
|
lockey.wLock();
|
|
this.locks.get().put(lockey, new LockeyHolder(lockey, true));
|
|
} else if (!holder.write) {
|
|
holder.lockey.rUnlock();
|
|
holder.lockey.wLock();
|
|
holder.write = true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void reset() {
|
|
try {
|
|
locks.get().values().forEach(holder -> {
|
|
if (holder.write)
|
|
holder.lockey.wUnlock();
|
|
else
|
|
holder.lockey.rUnlock();
|
|
});
|
|
locks.get().clear();
|
|
}catch (Exception e){
|
|
e.printStackTrace();
|
|
}
|
|
|
|
}
|
|
|
|
static class LockeyHolder implements Comparable<LockeyHolder> {
|
|
final Lockey lockey;
|
|
boolean write;
|
|
|
|
LockeyHolder(Lockey lockey, boolean write) {
|
|
this.lockey = lockey;
|
|
this.write = write;
|
|
}
|
|
|
|
@Override
|
|
public int compareTo(LockeyHolder o) {
|
|
return lockey.compareTo(o.lockey);
|
|
}
|
|
}
|
|
}
|