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 >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 { 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 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 { 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); } } }