[Feature] add for new
This commit is contained in:
@@ -3,6 +3,7 @@ package com.github.houbb.lock.redis.core;
|
||||
import com.github.houbb.lock.api.core.ILock;
|
||||
import com.github.houbb.lock.redis.constant.LockRedisConst;
|
||||
import com.github.houbb.wait.api.IWait;
|
||||
import com.github.houbb.wait.core.Waits;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
@@ -12,7 +13,7 @@ import java.util.concurrent.locks.Condition;
|
||||
* @author binbin.hou
|
||||
* @since 0.0.1
|
||||
*/
|
||||
public abstract class AbstractLockRedis implements ILock {
|
||||
public abstract class AbstractLock implements ILock {
|
||||
|
||||
/**
|
||||
* 锁等待
|
||||
@@ -20,7 +21,11 @@ public abstract class AbstractLockRedis implements ILock {
|
||||
*/
|
||||
private final IWait wait;
|
||||
|
||||
protected AbstractLockRedis(IWait wait) {
|
||||
public AbstractLock() {
|
||||
this.wait = Waits.threadSleep();
|
||||
}
|
||||
|
||||
protected AbstractLock(IWait wait) {
|
||||
this.wait = wait;
|
||||
}
|
||||
|
||||
@@ -68,8 +73,8 @@ public abstract class AbstractLockRedis implements ILock {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 等待 10ms
|
||||
wait.wait(TimeUnit.MILLISECONDS, 10);
|
||||
// 等待 1ms
|
||||
wait.wait(TimeUnit.MILLISECONDS, 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import com.github.houbb.wait.api.IWait;
|
||||
* @author binbin.hou
|
||||
* @since 0.0.1
|
||||
*/
|
||||
public class LockRedis extends AbstractLockRedis {
|
||||
public class LockRedis extends AbstractLock {
|
||||
|
||||
/**
|
||||
* redis 操作实现
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.github.houbb.lock.redis.core;
|
||||
|
||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* 自旋锁
|
||||
* @author binbin.hou
|
||||
* @since 0.0.2
|
||||
*/
|
||||
public class LockSpin extends AbstractLock {
|
||||
|
||||
/**
|
||||
* volatile 引用,保证线程间的可见性+易变性
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
private AtomicReference<Thread> owner =new AtomicReference<>();
|
||||
|
||||
@Override
|
||||
public void lock() {
|
||||
// 循环等待,直到获取到锁
|
||||
while (!tryLock()) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(String key) {
|
||||
Thread current = Thread.currentThread();
|
||||
// CAS
|
||||
return owner.compareAndSet(null, current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock(String key) {
|
||||
Thread current = Thread.currentThread();
|
||||
boolean result = owner.compareAndSet(current, null);
|
||||
if(!result) {
|
||||
throw new LockRuntimeException("解锁失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.github.houbb.lock.redis.core;
|
||||
|
||||
import com.github.houbb.heaven.util.util.DateUtil;
|
||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* 自旋锁-可重入
|
||||
* @author binbin.hou
|
||||
* @since 0.0.2
|
||||
*/
|
||||
public class LockSpinRe extends AbstractLock {
|
||||
|
||||
/**
|
||||
* volatile 引用,保证线程间的可见性+易变性
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
private AtomicReference<Thread> owner =new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* 计数统计类
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
private AtomicLong count = new AtomicLong(0);
|
||||
|
||||
@Override
|
||||
public void lock() {
|
||||
// 循环等待,直到获取到锁
|
||||
while (!tryLock()) {
|
||||
// sleep
|
||||
DateUtil.sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(String key) {
|
||||
Thread current = Thread.currentThread();
|
||||
// 判断是否已经拥有此锁
|
||||
if(current == owner.get()) {
|
||||
// 原子性自增 1
|
||||
count.incrementAndGet();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// CAS
|
||||
return owner.compareAndSet(null, current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock(String key) {
|
||||
Thread current = Thread.currentThread();
|
||||
|
||||
// 可重入实现
|
||||
if(owner.get() == current && count.get() != 0) {
|
||||
count.decrementAndGet();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = owner.compareAndSet(current, null);
|
||||
if(!result) {
|
||||
throw new LockRuntimeException("解锁失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.github.houbb.lock.redis.core;
|
||||
|
||||
import com.github.houbb.lock.redis.exception.LockRuntimeException;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* 等待通知的锁实现
|
||||
* @author binbin.hou
|
||||
* @since 0.0.2
|
||||
*/
|
||||
public class LockWaitNotify extends AbstractLock {
|
||||
|
||||
/**
|
||||
* volatile 引用,保证线程间的可见性+易变性
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
private AtomicReference<Thread> owner =new AtomicReference<>();
|
||||
|
||||
@Override
|
||||
public synchronized void lock() {
|
||||
while (!tryLock()) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
// 是否可以被打断
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(String key) {
|
||||
Thread current = Thread.currentThread();
|
||||
// CAS
|
||||
return owner.compareAndSet(null, current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unlock(String key) {
|
||||
Thread current = Thread.currentThread();
|
||||
boolean result = owner.compareAndSet(current, null);
|
||||
if(!result) {
|
||||
throw new LockRuntimeException("解锁失败");
|
||||
}
|
||||
|
||||
// 唤醒等待中的线程
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.github.houbb.lock.redis.exception;
|
||||
|
||||
/**
|
||||
* @author binbin.hou
|
||||
* @since 0.0.2
|
||||
*/
|
||||
public class LockRuntimeException extends RuntimeException {
|
||||
|
||||
public LockRuntimeException() {
|
||||
}
|
||||
|
||||
public LockRuntimeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public LockRuntimeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public LockRuntimeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public LockRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user