Compare commits
7 Commits
release_0.
...
release_0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ecd879763a | ||
|
|
d06effa306 | ||
|
|
bce83c6d1e | ||
|
|
2016605dfd | ||
|
|
d273441a72 | ||
|
|
2cc9eccdee | ||
|
|
4beac5f889 |
@@ -20,3 +20,9 @@
|
|||||||
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||||
|:---|:---|:---|:---|:--|
|
|:---|:---|:---|:---|:--|
|
||||||
| 1 | A | 常见锁添加 | 2020-9-2 14:45:40 | |
|
| 1 | A | 常见锁添加 | 2020-9-2 14:45:40 | |
|
||||||
|
|
||||||
|
# release_0.0.3
|
||||||
|
|
||||||
|
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||||
|
|:---|:---|:---|:---|:--|
|
||||||
|
| 1 | A | redis 锁独立,便于使用 | 2021-12-08 14:45:40 | |
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.2</version>
|
<version>0.0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,32 @@
|
|||||||
package com.github.houbb.lock.api.core;
|
package com.github.houbb.lock.api.core;
|
||||||
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读写锁定义
|
* 读写锁定义接口
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public interface IReadWriteLock extends ReadWriteLock {
|
public interface IReadWriteLock {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取读锁
|
||||||
|
* @since 0.0.2
|
||||||
|
*/
|
||||||
|
void lockRead();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放读锁
|
||||||
|
*/
|
||||||
|
void unlockRead();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取写锁
|
||||||
|
* @since 0.0.2
|
||||||
|
*/
|
||||||
|
void lockWrite();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放写锁
|
||||||
|
*/
|
||||||
|
void unlockWrite();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.github.houbb.lock.redis.support.operator;
|
package com.github.houbb.lock.api.support;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis 客户端
|
* 操作接口定义
|
||||||
|
*
|
||||||
|
* ps: 可以基于集中式数据库做操作
|
||||||
|
*
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.1
|
* @since 0.0.3
|
||||||
*/
|
*/
|
||||||
public interface IOperator {
|
public interface IOperator {
|
||||||
|
|
||||||
@@ -14,7 +17,7 @@ public interface IOperator {
|
|||||||
* @param requestId 请求标识
|
* @param requestId 请求标识
|
||||||
* @param expireTimeMills 超期时间
|
* @param expireTimeMills 超期时间
|
||||||
* @return 是否获取成功
|
* @return 是否获取成功
|
||||||
* @since 0.0.1
|
* @since 0.0.3
|
||||||
*/
|
*/
|
||||||
boolean lock(String lockKey, String requestId, int expireTimeMills);
|
boolean lock(String lockKey, String requestId, int expireTimeMills);
|
||||||
|
|
||||||
@@ -23,7 +26,7 @@ public interface IOperator {
|
|||||||
* @param lockKey 锁 key
|
* @param lockKey 锁 key
|
||||||
* @param requestId 请求标识
|
* @param requestId 请求标识
|
||||||
* @return 结果
|
* @return 结果
|
||||||
* @since 0.0.1
|
* @since 0.0.3
|
||||||
*/
|
*/
|
||||||
boolean unlock(String lockKey, String requestId);
|
boolean unlock(String lockKey, String requestId);
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.2</version>
|
<version>0.0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -37,11 +37,7 @@
|
|||||||
<artifactId>log-integration</artifactId>
|
<artifactId>log-integration</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--============================== OTHER ==============================-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>redis.clients</groupId>
|
|
||||||
<artifactId>jedis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.github.houbb.lock.redis.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用锁常量
|
||||||
|
*
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public final class LockConst {
|
||||||
|
|
||||||
|
private LockConst() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认的失效时间
|
||||||
|
*
|
||||||
|
* 暂时定为 30min
|
||||||
|
* @since 0.0.1
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_EXPIRE_MILLS = 1000 * 60 * 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认锁为全局锁
|
||||||
|
* @since 0.0.1
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_KEY = "GLOBAL";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.redis.core;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
import com.github.houbb.lock.redis.constant.LockConst;
|
||||||
import com.github.houbb.wait.api.IWait;
|
import com.github.houbb.wait.api.IWait;
|
||||||
import com.github.houbb.wait.core.Waits;
|
import com.github.houbb.wait.core.Waits;
|
||||||
|
|
||||||
@@ -41,12 +41,12 @@ public abstract class AbstractLock implements ILock {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryLock() {
|
public boolean tryLock() {
|
||||||
return tryLock(LockRedisConst.DEFAULT_KEY);
|
return tryLock(LockConst.DEFAULT_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unlock() {
|
public void unlock() {
|
||||||
unlock(LockRedisConst.DEFAULT_KEY);
|
unlock(LockConst.DEFAULT_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,7 +81,7 @@ public abstract class AbstractLock implements ILock {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
public synchronized boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
||||||
return tryLock(time, unit, LockRedisConst.DEFAULT_KEY);
|
return tryLock(time, unit, LockConst.DEFAULT_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.github.houbb.lock.redis.core;
|
||||||
|
|
||||||
|
import com.github.houbb.heaven.annotation.ThreadSafe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无任何锁的操作
|
||||||
|
*
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
@ThreadSafe
|
||||||
|
public class LockNone extends AbstractLock {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryLock(String key) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlock(String key) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.redis.core;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
@@ -9,32 +10,38 @@ import com.github.houbb.log.integration.core.LogFactory;
|
|||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public class LockReadWrite {
|
public class LockReadWrite implements IReadWriteLock {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(LockReadWrite.class);
|
private static final Log log = LogFactory.getLog(LockReadWrite.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读次数统计
|
* 读次数统计
|
||||||
*/
|
*/
|
||||||
private int readCount = 0;
|
private volatile int readCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写次数统计
|
* 写次数统计
|
||||||
*/
|
*/
|
||||||
private int writeCount = 0;
|
private volatile int writeCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取读锁,读锁在写锁不存在的时候才能获取
|
* 获取读锁,读锁在写锁不存在的时候才能获取
|
||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public synchronized void lockRead() throws InterruptedException {
|
@Override
|
||||||
|
public synchronized void lockRead() {
|
||||||
|
try {
|
||||||
// 写锁存在,需要wait
|
// 写锁存在,需要wait
|
||||||
while (!tryLockRead()) {
|
while (!tryLockRead()) {
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
readCount++;
|
readCount++;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.interrupted();
|
||||||
|
// 忽略打断
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +64,7 @@ public class LockReadWrite {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized void unlockRead() {
|
public synchronized void unlockRead() {
|
||||||
readCount--;
|
readCount--;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
@@ -67,7 +75,9 @@ public class LockReadWrite {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public synchronized void lockWrite() throws InterruptedException {
|
@Override
|
||||||
|
public synchronized void lockWrite() {
|
||||||
|
try {
|
||||||
// 写锁存在,需要wait
|
// 写锁存在,需要wait
|
||||||
while (!tryLockWrite()) {
|
while (!tryLockWrite()) {
|
||||||
wait();
|
wait();
|
||||||
@@ -75,6 +85,9 @@ public class LockReadWrite {
|
|||||||
|
|
||||||
// 此时已经不存在获取写锁的线程了,因此占坑,防止写锁饥饿
|
// 此时已经不存在获取写锁的线程了,因此占坑,防止写锁饥饿
|
||||||
writeCount++;
|
writeCount++;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.interrupted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,6 +116,7 @@ public class LockReadWrite {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized void unlockWrite() {
|
public synchronized void unlockWrite() {
|
||||||
writeCount--;
|
writeCount--;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.redis.core;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public class LockReadWriteOwner {
|
public class LockReadWriteOwner implements IReadWriteLock {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(LockReadWriteOwner.class);
|
private static final Log log = LogFactory.getLog(LockReadWriteOwner.class);
|
||||||
|
|
||||||
@@ -35,19 +36,24 @@ public class LockReadWriteOwner {
|
|||||||
/**
|
/**
|
||||||
* 写次数统计
|
* 写次数统计
|
||||||
*/
|
*/
|
||||||
private int writeCount = 0;
|
private volatile int writeCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取读锁,读锁在写锁不存在的时候才能获取
|
* 获取读锁,读锁在写锁不存在的时候才能获取
|
||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public synchronized void lockRead() throws InterruptedException {
|
@Override
|
||||||
|
public synchronized void lockRead() {
|
||||||
|
try {
|
||||||
// 写锁存在,需要wait
|
// 写锁存在,需要wait
|
||||||
while (!tryLockRead()) {
|
while (!tryLockRead()) {
|
||||||
log.debug("获取读锁失败,进入等待状态。");
|
log.debug("获取读锁失败,进入等待状态。");
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.interrupted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +81,7 @@ public class LockReadWriteOwner {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized void unlockRead() {
|
public synchronized void unlockRead() {
|
||||||
Thread currentThread = Thread.currentThread();
|
Thread currentThread = Thread.currentThread();
|
||||||
Integer readCount = readCountMap.get(currentThread);
|
Integer readCount = readCountMap.get(currentThread);
|
||||||
@@ -83,6 +90,7 @@ public class LockReadWriteOwner {
|
|||||||
throw new RuntimeException("当前线程未持有任何读锁,释放锁失败!");
|
throw new RuntimeException("当前线程未持有任何读锁,释放锁失败!");
|
||||||
} else {
|
} else {
|
||||||
log.debug("释放读锁,唤醒所有等待线程。");
|
log.debug("释放读锁,唤醒所有等待线程。");
|
||||||
|
readCountMap.remove(currentThread);
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +100,9 @@ public class LockReadWriteOwner {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public synchronized void lockWrite() throws InterruptedException {
|
@Override
|
||||||
|
public synchronized void lockWrite() {
|
||||||
|
try {
|
||||||
// 写锁存在,需要wait
|
// 写锁存在,需要wait
|
||||||
while (!tryLockWrite()) {
|
while (!tryLockWrite()) {
|
||||||
wait();
|
wait();
|
||||||
@@ -100,6 +110,9 @@ public class LockReadWriteOwner {
|
|||||||
|
|
||||||
// 此时已经不存在获取写锁的线程了,因此占坑,防止写锁饥饿
|
// 此时已经不存在获取写锁的线程了,因此占坑,防止写锁饥饿
|
||||||
writeCount++;
|
writeCount++;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.interrupted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,6 +144,7 @@ public class LockReadWriteOwner {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized void unlockWrite() {
|
public synchronized void unlockWrite() {
|
||||||
boolean toNullResult = writeOwner.compareAndSet(Thread.currentThread(), null);
|
boolean toNullResult = writeOwner.compareAndSet(Thread.currentThread(), null);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.redis.core;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public class LockReadWriteRe {
|
public class LockReadWriteRe implements IReadWriteLock {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(LockReadWriteRe.class);
|
private static final Log log = LogFactory.getLog(LockReadWriteRe.class);
|
||||||
|
|
||||||
@@ -35,19 +36,24 @@ public class LockReadWriteRe {
|
|||||||
/**
|
/**
|
||||||
* 写次数统计
|
* 写次数统计
|
||||||
*/
|
*/
|
||||||
private int writeCount = 0;
|
private volatile int writeCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取读锁,读锁在写锁不存在的时候才能获取
|
* 获取读锁,读锁在写锁不存在的时候才能获取
|
||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public synchronized void lockRead() throws InterruptedException {
|
@Override
|
||||||
|
public synchronized void lockRead() {
|
||||||
|
try {
|
||||||
// 写锁存在,需要wait
|
// 写锁存在,需要wait
|
||||||
while (!tryLockRead()) {
|
while (!tryLockRead()) {
|
||||||
log.debug("获取读锁失败,进入等待状态。");
|
log.debug("获取读锁失败,进入等待状态。");
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.interrupted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,6 +86,7 @@ public class LockReadWriteRe {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized void unlockRead() {
|
public synchronized void unlockRead() {
|
||||||
Thread currentThread = Thread.currentThread();
|
Thread currentThread = Thread.currentThread();
|
||||||
Integer readCount = readCountMap.get(currentThread);
|
Integer readCount = readCountMap.get(currentThread);
|
||||||
@@ -106,7 +113,9 @@ public class LockReadWriteRe {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
public synchronized void lockWrite() throws InterruptedException {
|
@Override
|
||||||
|
public synchronized void lockWrite() {
|
||||||
|
try {
|
||||||
// 写锁存在,需要wait
|
// 写锁存在,需要wait
|
||||||
while (!tryLockWrite()) {
|
while (!tryLockWrite()) {
|
||||||
log.debug("获取写锁失败,进入等待状态。");
|
log.debug("获取写锁失败,进入等待状态。");
|
||||||
@@ -115,6 +124,9 @@ public class LockReadWriteRe {
|
|||||||
|
|
||||||
// 此时已经不存在获取写锁的线程了,因此占坑,防止写锁饥饿
|
// 此时已经不存在获取写锁的线程了,因此占坑,防止写锁饥饿
|
||||||
writeCount++;
|
writeCount++;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.interrupted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,6 +164,7 @@ public class LockReadWriteRe {
|
|||||||
*
|
*
|
||||||
* @since 0.0.2
|
* @since 0.0.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized void unlockWrite() {
|
public synchronized void unlockWrite() {
|
||||||
Thread currentThread = Thread.currentThread();
|
Thread currentThread = Thread.currentThread();
|
||||||
// 多次重入释放(当次数多于1时直接返回,否则需要释放 owner 信息)
|
// 多次重入释放(当次数多于1时直接返回,否则需要释放 owner 信息)
|
||||||
@@ -173,7 +186,7 @@ public class LockReadWriteRe {
|
|||||||
/**
|
/**
|
||||||
* 释放写锁并且通知
|
* 释放写锁并且通知
|
||||||
*/
|
*/
|
||||||
private void unlockWriteNotify() {
|
private synchronized void unlockWriteNotify() {
|
||||||
writeCount--;
|
writeCount--;
|
||||||
log.debug("释放写锁成功,唤醒所有等待线程。");
|
log.debug("释放写锁成功,唤醒所有等待线程。");
|
||||||
notifyAll();
|
notifyAll();
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package com.github.houbb.lock.redis.core;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
|
import com.github.houbb.lock.api.core.IReadWriteLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁工具
|
||||||
|
*
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public final class Locks {
|
||||||
|
|
||||||
|
private Locks(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static ILock none() {
|
||||||
|
return new LockNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读写锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static IReadWriteLock readWrite() {
|
||||||
|
return new LockReadWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读写锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static IReadWriteLock readWriteOwner() {
|
||||||
|
return new LockReadWriteOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可重入读写锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static IReadWriteLock readWriteRe() {
|
||||||
|
return new LockReadWriteRe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自旋锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static ILock spin() {
|
||||||
|
return new LockSpin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可重入自旋锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static ILock spinRe() {
|
||||||
|
return new LockSpinRe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等待通知锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static ILock waitNotify() {
|
||||||
|
return new LockWaitNotify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可重入等待通知锁
|
||||||
|
* @return 锁
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
public static ILock waitNotifyRe() {
|
||||||
|
return new LockWaitNotifyRe();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
lock-redis/pom.xml
Normal file
28
lock-redis/pom.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?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>lock</artifactId>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<version>0.0.3</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>lock-redis</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!--============================== SELF ==============================-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--============================== OTHER ==============================-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -3,8 +3,8 @@ package com.github.houbb.lock.redis.bs;
|
|||||||
import com.github.houbb.id.api.Id;
|
import com.github.houbb.id.api.Id;
|
||||||
import com.github.houbb.id.core.core.Ids;
|
import com.github.houbb.id.core.core.Ids;
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
import com.github.houbb.lock.redis.core.LockRedis;
|
import com.github.houbb.lock.api.support.IOperator;
|
||||||
import com.github.houbb.lock.redis.support.operator.IOperator;
|
import com.github.houbb.lock.redis.lock.LockRedis;
|
||||||
import com.github.houbb.wait.api.IWait;
|
import com.github.houbb.wait.api.IWait;
|
||||||
import com.github.houbb.wait.core.Waits;
|
import com.github.houbb.wait.core.Waits;
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ public final class LockRedisBs {
|
|||||||
private IWait wait = Waits.threadSleep();
|
private IWait wait = Waits.threadSleep();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 等待实现
|
* ID 实现
|
||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
*/
|
*/
|
||||||
private Id id = Ids.uuid32();
|
private Id id = Ids.uuid32();
|
||||||
@@ -2,9 +2,9 @@ package com.github.houbb.lock.redis.exception;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.1
|
* @since 0.0.3
|
||||||
*/
|
*/
|
||||||
public class LockRedisException extends RuntimeException {
|
public class LockRedisException extends LockRuntimeException {
|
||||||
|
|
||||||
public LockRedisException() {
|
public LockRedisException() {
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package com.github.houbb.lock.redis.exception;
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package com.github.houbb.lock.redis.core;
|
package com.github.houbb.lock.redis.lock;
|
||||||
|
|
||||||
import com.github.houbb.heaven.util.lang.StringUtil;
|
import com.github.houbb.heaven.util.lang.StringUtil;
|
||||||
import com.github.houbb.id.api.Id;
|
import com.github.houbb.id.api.Id;
|
||||||
import com.github.houbb.id.core.util.IdThreadLocalHelper;
|
import com.github.houbb.id.core.util.IdThreadLocalHelper;
|
||||||
|
import com.github.houbb.lock.api.support.IOperator;
|
||||||
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
||||||
|
import com.github.houbb.lock.redis.core.AbstractLock;
|
||||||
import com.github.houbb.lock.redis.exception.LockRedisException;
|
import com.github.houbb.lock.redis.exception.LockRedisException;
|
||||||
import com.github.houbb.lock.redis.support.operator.IOperator;
|
|
||||||
import com.github.houbb.wait.api.IWait;
|
import com.github.houbb.wait.api.IWait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package com.github.houbb.lock.redis;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.houbb.lock.redis.support.operator.impl;
|
package com.github.houbb.lock.redis.support.operator;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.api.support.IOperator;
|
||||||
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
||||||
import com.github.houbb.lock.redis.support.operator.IOperator;
|
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>0.0.2</version>
|
<version>0.0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -16,6 +16,10 @@
|
|||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>lock-core</artifactId>
|
<artifactId>lock-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.github.houbb.lock.test;
|
||||||
|
|
||||||
|
import java.util.concurrent.Phaser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class MyPhaser extends Phaser {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onAdvance(int phase, int registeredParties) {
|
||||||
|
switch (phase) {
|
||||||
|
case 0 :
|
||||||
|
System.out.println("上半场完成");
|
||||||
|
return false;
|
||||||
|
case 1:
|
||||||
|
System.out.println("下半场完成");
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.github.houbb.lock.test;
|
||||||
|
|
||||||
|
import java.util.concurrent.Phaser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class PhaserDemo {
|
||||||
|
|
||||||
|
private static class GameRunnable implements Runnable {
|
||||||
|
|
||||||
|
private final Phaser phaser;
|
||||||
|
|
||||||
|
private GameRunnable(Phaser phaser) {
|
||||||
|
this.phaser = phaser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//参加上半场比赛
|
||||||
|
System.out.println("玩家-"+Thread.currentThread().getName()+":参加上半场比赛");
|
||||||
|
//执行这个方法的话会等所有的选手都完成了之后再继续下面的方法
|
||||||
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|
||||||
|
|
||||||
|
// 下半场
|
||||||
|
//参加上半场比赛
|
||||||
|
System.out.println("玩家-"+Thread.currentThread().getName()+":参加下半场比赛");
|
||||||
|
//执行这个方法的话会等所有的选手都完成了之后再继续下面的方法
|
||||||
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int nums = 3;
|
||||||
|
Phaser phaser = new MyPhaser();
|
||||||
|
|
||||||
|
//注册一次表示 phaser 维护的线程个数
|
||||||
|
phaser.register();
|
||||||
|
|
||||||
|
for(int i = 0; i < nums; i++) {
|
||||||
|
phaser.register();
|
||||||
|
|
||||||
|
Thread thread = new Thread(new GameRunnable(phaser));
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
//后续阶段主线程就不参加了
|
||||||
|
phaser.arriveAndDeregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class ArrayBlockingQueueDemo {
|
||||||
|
|
||||||
|
private ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
|
||||||
|
|
||||||
|
public void put(final String put) throws InterruptedException {
|
||||||
|
System.out.println("设置开始");
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
queue.put(put);
|
||||||
|
System.out.println("设置完成: " + put);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void take() throws InterruptedException {
|
||||||
|
System.out.println("获取开始");
|
||||||
|
String take = queue.take();
|
||||||
|
System.out.println("获取成功: " + take);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final ArrayBlockingQueueDemo queueTest = new ArrayBlockingQueueDemo();
|
||||||
|
// 写入线程
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
queueTest.put(i+"T");
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
// 读取线程
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
queueTest.take();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class ConcurrentLinkedQueueTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void helloTest() {
|
||||||
|
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
// add() 将指定元素插入此队列的尾部。
|
||||||
|
queue.add("add");
|
||||||
|
|
||||||
|
// offer() 将指定元素插入此队列的尾部。
|
||||||
|
queue.offer("offer");
|
||||||
|
|
||||||
|
// peek() 获取但不移除此队列的头;如果此队列为空,则返回 null
|
||||||
|
String value = queue.peek();
|
||||||
|
System.out.println("PEEK: " + value);
|
||||||
|
|
||||||
|
// poll() 获取并移除此队列的头,如果此队列为空,则返回 null。
|
||||||
|
String poll = queue.poll();
|
||||||
|
System.out.println("POLL: " + poll);
|
||||||
|
|
||||||
|
// remove() 移除 从队列中移除指定元素的单个实例(如果存在)。
|
||||||
|
boolean remove = queue.remove("offer");
|
||||||
|
System.out.println("Remove result: " + remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class CowArraySetDemo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读线程
|
||||||
|
*/
|
||||||
|
private static class ReadTask implements Runnable {
|
||||||
|
Set<String> set;
|
||||||
|
|
||||||
|
public ReadTask(Set<String> set) {
|
||||||
|
this.set = set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
System.out.println(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 写线程
|
||||||
|
*/
|
||||||
|
private static class WriteTask implements Runnable {
|
||||||
|
private Set<String> set;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public WriteTask(Set<String> set, String value) {
|
||||||
|
this.set = set;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
set.remove(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final int NUM = 5;
|
||||||
|
Set<String> set = new CopyOnWriteArraySet<>();
|
||||||
|
for (int i = 0; i < NUM; i++) {
|
||||||
|
set.add("main_" + i);
|
||||||
|
}
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(NUM);
|
||||||
|
for (int i = 0; i < NUM; i++) {
|
||||||
|
executorService.execute(new WriteTask(set, "main_" + i));
|
||||||
|
executorService.execute(new ReadTask(set));
|
||||||
|
}
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import java.util.concurrent.DelayQueue;
|
||||||
|
import java.util.concurrent.Delayed;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @see java.util.concurrent.DelayQueue
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class DelayQueueDemo {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入线程
|
||||||
|
* @author 老马啸西风
|
||||||
|
*/
|
||||||
|
private static class WriteThread extends Thread {
|
||||||
|
|
||||||
|
private final DelayQueue<DelayElem> delayQueue;
|
||||||
|
|
||||||
|
private WriteThread(DelayQueue<DelayElem> delayQueue) {
|
||||||
|
this.delayQueue = delayQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
try {
|
||||||
|
TimeUnit.MILLISECONDS.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayElem element = new DelayElem(1000,i+"test");
|
||||||
|
delayQueue.offer(element);
|
||||||
|
System.out.println(System.currentTimeMillis() + " 放入元素 " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取线程
|
||||||
|
* @author 老马啸西风
|
||||||
|
*/
|
||||||
|
private static class ReadThread extends Thread {
|
||||||
|
|
||||||
|
private final DelayQueue<DelayElem> delayQueue;
|
||||||
|
|
||||||
|
private ReadThread(DelayQueue<DelayElem> delayQueue) {
|
||||||
|
this.delayQueue = delayQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true){
|
||||||
|
try {
|
||||||
|
DelayElem element = delayQueue.take();
|
||||||
|
System.out.println(System.currentTimeMillis() +" 获取元素:" + element);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class DelayElem implements Delayed {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 延迟时间
|
||||||
|
*/
|
||||||
|
private final long delay;
|
||||||
|
/**
|
||||||
|
* 到期时间
|
||||||
|
*/
|
||||||
|
private final long expire;
|
||||||
|
/**
|
||||||
|
* 数据
|
||||||
|
*/
|
||||||
|
private final String msg;
|
||||||
|
|
||||||
|
private DelayElem(long delay, String msg) {
|
||||||
|
this.delay = delay;
|
||||||
|
this.msg = msg;
|
||||||
|
//到期时间 = 当前时间+延迟时间
|
||||||
|
this.expire = System.currentTimeMillis() + this.delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要实现的接口,获得延迟时间
|
||||||
|
*
|
||||||
|
* 用过期时间-当前时间
|
||||||
|
* @param unit 时间单位
|
||||||
|
* @return 延迟时间
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getDelay(TimeUnit unit) {
|
||||||
|
return unit.convert(this.expire - System.currentTimeMillis() , TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于延迟队列内部比较排序
|
||||||
|
* <p>
|
||||||
|
* 当前时间的延迟时间 - 比较对象的延迟时间
|
||||||
|
*
|
||||||
|
* @param o 比较对象
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(Delayed o) {
|
||||||
|
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DelayElem{" +
|
||||||
|
"delay=" + delay +
|
||||||
|
", expire=" + expire +
|
||||||
|
", msg='" + msg + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
DelayQueue<DelayElem> delayQueue = new DelayQueue<>();
|
||||||
|
|
||||||
|
new WriteThread(delayQueue).start();
|
||||||
|
new ReadThread(delayQueue).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingDeque;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class LinkedBlockingDequeDemo {
|
||||||
|
|
||||||
|
private static class Producer implements Runnable{
|
||||||
|
private BlockingDeque<Integer> queue;
|
||||||
|
public Producer(BlockingDeque<Integer> queue) {
|
||||||
|
this.queue = queue;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
Integer num = ThreadLocalRandom.current().nextInt(100);
|
||||||
|
queue.put(num);
|
||||||
|
System.out.println(String.format("%s producer a num %d",Thread.currentThread().getName(),num));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Consumer implements Runnable{
|
||||||
|
private BlockingDeque<Integer> queue;
|
||||||
|
public Consumer(BlockingDeque<Integer> queue) {
|
||||||
|
this.queue = queue;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
System.out.println(String.format("%s consume a num %d",Thread.currentThread().getName(),queue.take()));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
BlockingDeque<Integer> queue = new LinkedBlockingDeque<>(100);
|
||||||
|
new Thread(new Producer(queue),"Producer").start();
|
||||||
|
new Thread(new Consumer(queue),"Consumer").start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class LinkedBlockingQueueDemo {
|
||||||
|
|
||||||
|
private BlockingQueue<String> queue = new LinkedBlockingQueue<>(3);
|
||||||
|
|
||||||
|
public void put(final String put) throws InterruptedException {
|
||||||
|
System.out.println("设置开始");
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
queue.put(put);
|
||||||
|
System.out.println("设置完成: " + put);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void take() throws InterruptedException {
|
||||||
|
System.out.println("获取开始");
|
||||||
|
String take = queue.take();
|
||||||
|
System.out.println("获取成功: " + take);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final LinkedBlockingQueueDemo queueTest = new LinkedBlockingQueueDemo();
|
||||||
|
// 写入线程
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
queueTest.put(i+"T");
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
// 读取线程
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
queueTest.take();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
import java.util.concurrent.PriorityBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class PriorityBlockingQueueDemo {
|
||||||
|
|
||||||
|
private static class User implements Comparable<User> {
|
||||||
|
|
||||||
|
private final int order;
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private User(int order, String name) {
|
||||||
|
this.order = order;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(User o) {
|
||||||
|
return this.order - o.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User{" +
|
||||||
|
"order=" + order +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PriorityBlockingQueue<User> queue = new PriorityBlockingQueue<>();
|
||||||
|
|
||||||
|
public void put(final User user) throws InterruptedException {
|
||||||
|
System.out.println("设置开始");
|
||||||
|
queue.put(user);
|
||||||
|
System.out.println("设置完成: " + user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void take() throws InterruptedException {
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
System.out.println("获取开始");
|
||||||
|
User take = queue.take();
|
||||||
|
System.out.println("获取成功: " + take);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final PriorityBlockingQueueDemo queueTest = new PriorityBlockingQueueDemo();
|
||||||
|
// 写入线程
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
int order = ThreadLocalRandom.current().nextInt(10);
|
||||||
|
User user = new User(order, i+"-user");
|
||||||
|
queueTest.put(user);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
// 读取线程
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
queueTest.take();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.github.houbb.lock.test.lock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
* @see java.util.concurrent.SynchronousQueue
|
||||||
|
*/
|
||||||
|
public class SynchronousQueueDemo {
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.github.houbb.lock.test;
|
package com.github.houbb.lock.test.redis;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
@@ -8,6 +9,7 @@ import redis.clients.jedis.Jedis;
|
|||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
*/
|
*/
|
||||||
|
@Ignore
|
||||||
public class JedisTest {
|
public class JedisTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package com.github.houbb.lock.test;
|
package com.github.houbb.lock.test.redis;
|
||||||
|
|
||||||
import com.github.houbb.lock.api.core.ILock;
|
import com.github.houbb.lock.api.core.ILock;
|
||||||
|
import com.github.houbb.lock.api.support.IOperator;
|
||||||
import com.github.houbb.lock.redis.bs.LockRedisBs;
|
import com.github.houbb.lock.redis.bs.LockRedisBs;
|
||||||
import com.github.houbb.lock.redis.support.operator.IOperator;
|
import com.github.houbb.lock.redis.support.operator.JedisOperator;
|
||||||
import com.github.houbb.lock.redis.support.operator.impl.JedisOperator;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ import redis.clients.jedis.Jedis;
|
|||||||
* @author binbin.hou
|
* @author binbin.hou
|
||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
*/
|
*/
|
||||||
|
@Ignore
|
||||||
public class LockRedisTest {
|
public class LockRedisTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
10
pom.xml
10
pom.xml
@@ -5,11 +5,12 @@
|
|||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>0.0.2</version>
|
<version>0.0.3</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>lock-api</module>
|
<module>lock-api</module>
|
||||||
<module>lock-core</module>
|
<module>lock-core</module>
|
||||||
<module>lock-test</module>
|
<module>lock-test</module>
|
||||||
|
<module>lock-redis</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
|
|
||||||
<!--============================== INTER ==============================-->
|
<!--============================== INTER ==============================-->
|
||||||
<plugin.gen.version>1.0.6</plugin.gen.version>
|
<plugin.gen.version>1.0.6</plugin.gen.version>
|
||||||
<heaven.version>0.1.114</heaven.version>
|
<heaven.version>0.1.148</heaven.version>
|
||||||
<id.version>0.0.6</id.version>
|
<id.version>0.0.6</id.version>
|
||||||
<wait.version>0.0.1</wait.version>
|
<wait.version>0.0.1</wait.version>
|
||||||
<log-integration.version>1.1.8</log-integration.version>
|
<log-integration.version>1.1.8</log-integration.version>
|
||||||
@@ -56,6 +57,11 @@
|
|||||||
<artifactId>lock-core</artifactId>
|
<artifactId>lock-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-redis</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--============================== INTER ==============================-->
|
<!--============================== INTER ==============================-->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ ECHO "============================= RELEASE START..."
|
|||||||
|
|
||||||
:: 版本号信息(需要手动指定)
|
:: 版本号信息(需要手动指定)
|
||||||
:::: 旧版本名称
|
:::: 旧版本名称
|
||||||
SET version=0.0.2
|
SET version=0.0.3
|
||||||
:::: 新版本名称
|
:::: 新版本名称
|
||||||
SET newVersion=0.0.3
|
SET newVersion=0.0.4
|
||||||
:::: 组织名称
|
:::: 组织名称
|
||||||
SET groupName=com.github.houbb
|
SET groupName=com.github.houbb
|
||||||
:::: 项目名称
|
:::: 项目名称
|
||||||
|
|||||||
Reference in New Issue
Block a user