zhouhao преди 8 години
родител
ревизия
a2524a1435

+ 15 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/pom.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-concurrent-lock</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-concurrent-lock-api</artifactId>
+
+
+</project>

+ 31 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/AbstactLocakFactory.java

@@ -0,0 +1,31 @@
+package org.hswebframework.web.concurrent.lock;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public abstract class AbstactLocakFactory implements LockFactory {
+    private Map<String, Lock>          lockStore          = new ConcurrentHashMap<>(128);
+    private Map<String, ReadWriteLock> readWriteLockStore = new ConcurrentHashMap<>(128);
+
+    @Override
+    public Lock getLock(String lockKey) {
+        return lockStore.computeIfAbsent(lockKey, this::createLock);
+    }
+
+    @Override
+    public ReadWriteLock getReadWriteLock(String lockKey) {
+        return readWriteLockStore.computeIfAbsent(lockKey, this::createReadWriteLock);
+    }
+
+    protected abstract Lock createLock(String lockKey);
+
+    protected abstract ReadWriteLock createReadWriteLock(String lockKey);
+
+}

+ 18 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/LockFactory.java

@@ -0,0 +1,18 @@
+package org.hswebframework.web.concurrent.lock;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+
+/**
+ * 锁工厂,用于创建获取锁
+ *
+ * @author zhouhao
+ * @see Lock
+ * @see ReadWriteLock
+ * @since 3.0
+ */
+public interface LockFactory {
+    Lock getLock(String lockKey);
+
+    ReadWriteLock getReadWriteLock(String lockKey);
+}

+ 27 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/SimpleLocakFactory.java

@@ -0,0 +1,27 @@
+package org.hswebframework.web.concurrent.lock;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * 使用jdk的锁实现
+ *
+ * @author zhouhao
+ * @see ReentrantLock
+ * @see ReentrantReadWriteLock
+ * @see AbstactLocakFactory
+ * @since 3.0
+ */
+public class SimpleLocakFactory extends AbstactLocakFactory {
+    @Override
+    protected synchronized Lock createLock(String lockKey) {
+        return new ReentrantLock();
+    }
+
+    @Override
+    protected synchronized ReadWriteLock createReadWriteLock(String lockKey) {
+        return new ReentrantReadWriteLock();
+    }
+}

+ 83 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/test/java/org/hswebframework/web/concurrent/lok/SimpleLockTests.java

@@ -0,0 +1,83 @@
+package org.hswebframework.web.concurrent.lok;
+
+import org.hswebframework.web.concurrent.lock.LockFactory;
+import org.hswebframework.web.concurrent.lock.SimpleLocakFactory;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+import java.math.BigDecimal;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.function.Consumer;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class SimpleLockTests {
+
+    private LockFactory lockFactory = new SimpleLocakFactory();
+
+    private long counter = 0;
+
+    @Test
+    public void testLock() throws InterruptedException {
+        counter = 0;
+        Lock lock = lockFactory.getLock("foo");
+        for (int i = 0; i < 100; i++) {
+            new Thread(() -> {
+                lock.lock();
+                for (int i1 = 0; i1 < 100; i1++) {
+                    counter++;
+                }
+                lock.unlock();
+            }).start();
+        }
+        Thread.sleep(1000);
+        Assert.assertEquals(counter, 100 * 100);
+    }
+
+    @Test
+    public void testReadWriteLock() throws InterruptedException {
+        counter = 0;
+        ReadWriteLock readWriteLock = lockFactory.getReadWriteLock("foo");
+
+        Lock readLock = readWriteLock.readLock();
+
+        Lock writeLock = readWriteLock.writeLock();
+        Consumer<Long>[] consumer = new Consumer[1];
+        consumer[0] = System.out::println;
+        for (int i = 0; i < 10; i++) {
+            new Thread(() -> {
+                for (int i1 = 0; i1 < 10; i1++) {
+                    try {
+                        Thread.sleep(500);
+                    } catch (InterruptedException ignored) {
+                    }
+                    writeLock.lock();
+                    long tmp = ++counter;
+
+                    //判断增加的值与 读取的值一致
+                    consumer[0] = l -> Assert.assertEquals(Long.valueOf(tmp), l);
+                    System.out.println("write:" + counter);
+                    writeLock.unlock();
+                }
+            }).start();
+            new Thread(() -> {
+                for (int i1 = 0; i1 < 10; i1++) {
+                    try {
+                        Thread.sleep(500);
+                    } catch (InterruptedException ignored) {
+                    }
+                    readLock.lock();
+                    consumer[0].accept(counter);
+                    System.out.println("read:" + counter);
+                    readLock.unlock();
+                }
+            }).start();
+        }
+        Thread.sleep(5000);
+    }
+}