ting.yin 4 سال پیش
والد
کامیت
9de6a555a7
1فایلهای تغییر یافته به همراه195 افزوده شده و 0 حذف شده
  1. 195 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/TaskLock.java

+ 195 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/TaskLock.java

@@ -0,0 +1,195 @@
+package cn.com.qmth.stmms.biz.utils;
+
+/**
+ * 链表模式实现的任务互斥锁工具
+ */
+public class TaskLock {
+
+    // 固定头节点
+    private LockNode head;
+
+    // 总量计数
+    private int count;
+
+    public TaskLock() {
+        head = new LockNode(0, 0, 0);
+        count = 0;
+    }
+
+    public synchronized boolean add(Object id, int number, Object owner) {
+        if (head.next == null) {
+            head.append(id, number, owner);
+            count++;
+            return true;
+        } else {
+            LockNode node = head.next;
+            while (true) {
+                // id+number,只能被一个owner获取
+                if (node.isId(id) && node.isNumber(number)) {
+                    return node.isOwner(owner);
+                }
+                // id只能被一个owner领取一个number
+                else if (node.isId(id) && node.isOwner(owner)) {
+                    return node.isNumber(number);
+                }
+                // 跳到下一个node
+                else if (node.hasNext()) {
+                    node = node.next;
+                }
+                // 可以领取
+                else {
+                    node.append(id, number, owner);
+                    count++;
+                    return true;
+                }
+            }
+        }
+    }
+
+    public synchronized boolean exist(Object id, int number, Object owner) {
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.isId(id) && node.isNumber(number)) {
+                return node.isOwner(owner);
+            } else {
+                node = node.next;
+            }
+        }
+        return false;
+    }
+
+    public synchronized boolean remove(Object id, int number, Object owner) {
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.isId(id) && node.isNumber(number)) {
+                if (node.isOwner(owner)) {
+                    node.remove();
+                    count--;
+                    return true;
+                } else {
+                    return false;
+                }
+            } else {
+                node = node.next;
+            }
+        }
+        return false;
+    }
+
+    public synchronized void clear() {
+        head.next = null;
+        count = 0;
+    }
+
+    public synchronized void clear(Object owner) {
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.isOwner(owner)) {
+                node.remove();
+                count--;
+            }
+            node = node.next;
+        }
+    }
+
+    public synchronized void clear(long expireTime) {
+        long current = System.currentTimeMillis();
+        LockNode node = head.next;
+        while (node != null) {
+            if ((current - node.time) > expireTime) {
+                node.remove();
+                count--;
+            }
+            node = node.next;
+        }
+    }
+
+    public synchronized boolean refresh(Object id, int number, Object owner) {
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.isId(id) && node.isNumber(number) && node.isOwner(owner)) {
+                node.time = System.currentTimeMillis();
+                return true;
+            }
+            node = node.next;
+        }
+        return false;
+    }
+
+    public synchronized boolean refresh(Object owner) {
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.isOwner(owner)) {
+                node.time = System.currentTimeMillis();
+                return true;
+            }
+            node = node.next;
+        }
+        return false;
+    }
+
+    public int count() {
+        return count;
+    }
+
+    public int count(Object owner) {
+        int count = 0;
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.isOwner(owner)) {
+                count++;
+            }
+            node = node.next;
+        }
+        return count;
+    }
+
+    private static class LockNode {
+
+        private LockNode previous;
+
+        private LockNode next;
+
+        private Object id;
+
+        private int number;
+
+        private Object owner;
+
+        private long time;
+
+        LockNode(Object id, int number, Object owner) {
+            this.id = id;
+            this.number = number;
+            this.owner = owner;
+            this.time = System.currentTimeMillis();
+        }
+
+        private boolean hasNext() {
+            return this.next != null;
+        }
+
+        private boolean isId(Object id) {
+            return this.id.equals(id);
+        }
+
+        private boolean isNumber(int number) {
+            return this.number == number;
+        }
+
+        private boolean isOwner(Object owner) {
+            return this.owner.equals(owner);
+        }
+
+        private void remove() {
+            this.previous.next = this.next;
+        }
+
+        private void append(Object id, int number, Object owner) {
+            LockNode node = new LockNode(id, number, owner);
+            this.next = node;
+            node.previous = this;
+        }
+    }
+
+}