miduo_server/gamecommon/src/main/java/util/Lockeys.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);
}
}
}