重点在于:
- 如果一台机器中没有线程获取到锁,那么它就应该不断的自旋拿锁,避免无限等待
- 给锁设置失效时间,避免持有锁的线程down机后发生死锁问题
- 使用单线程的线程池周期性的给锁续命,避免持有锁的时间内发生锁失效
可以扩展的地方:
- 使用分布式事务解决 redis 集群下的锁失效问题。即主redis down机后,没来得及把锁同步到其他redis
这样解决会有严重的性能问题,所以我默认没有实现,可以使用该锁自定义实现
刚开始拿锁的时候之所以没有只让一个线程拿锁,其余线程等待,是考虑到线程阻塞的性能问题。
public class RedisReentrantLock implements Lock {
private final Sync sync;
public RedisReentrantLock(StringRedisTemplate stringRedisTemplate, String key) {
sync = new Sync(stringRedisTemplate, key);
}
private static class Sync extends AbstractQueuedSynchronizer {
private final StringRedisTemplate stringRedisTemplate;
private final String key;
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private TimeUnit unit = TimeUnit.MILLISECONDS;
private int ex = 10;
public Sync(StringRedisTemplate stringRedisTemplate, String key) {
this.stringRedisTemplate = stringRedisTemplate;
this.key = key;
}
@Override
protected boolean tryAcquire(int arg) {
final Thread current = Thread.currentThread