失败无限重试- 多个线程竞争,第一个拿到锁第二个会无限重试

RLock lock = redisson.getLock("码哥字节");

try {

 

  // 1.最常用的第一种写法

  lock.lock();

 

  // 执行业务逻辑

  .....

 

} finally {

  lock.unlock();

}

 

拿锁失败时会不停的重试,具有Watch Dog 自动延期机制,默认续30s 每隔30/3=10 秒续到30s。

watchDog 只有在未显示指定加锁超时时间(leaseTime)时才会生效。

 

 

失败超时重试,自动续命

// 第一次失败后,尝试拿锁10s后停止重试,获取失败返回false,具有Watch Dog 自动延期机制, 默认续30s 业务逻辑没执行完会自动续期

boolean flag = lock.tryLock(10, TimeUnit.SECONDS);

 

 

超时自动释放锁

// 没有Watch Dog ,10s后自动释放,不需要调用 unlock 释放锁。

lock.lock(10, TimeUnit.SECONDS);

 

超时重试,自动解锁

// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁,没有 Watch dog

boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);

if (res) {

   try {

     ...

   } finally {

       lock.unlock();

   }

}

 

 

具体使用方法详见下面代码

 public void  lock() throws InterruptedException{

        log.info("线程:{},进入方法",Thread.currentThread().getName());

        RLock rLock = redissonClient.getLock("lock");

        //加锁:锁的有效期默认30秒

        rLock.lock();

        long timeToLive = rLock.remainTimeToLive();

        log.info("线程:{},获得锁,锁存活时间:{}S",Thread.currentThread().getName(),timeToLive/1000);

        //休眠一下

        Thread.sleep(2000);

   //失败的线程会一直重试,直到获取成功

        //如果主线程未释放,且当前锁未调用unlock方法,则进入到watchDog机制

        //如果主线程未释放,且当前锁调用unlock方法,则直接释放锁

        rLock.unlock();

        log.info("线程:{},释放锁",Thread.currentThread().getName());

    }

 

    public void  lockLaseTime() throws InterruptedException{

        log.info("线程:{},进入方法",Thread.currentThread().getName());

        RLock rLock = redissonClient.getLock("lockLaseTime");

        //加锁 上面是默认30秒,

        //这里可以手动设置锁的有效时间,锁到期后会自动释放的

        rLock.lock(10,TimeUnit.SECONDS);

        long timeToLive = rLock.remainTimeToLive();

        log.info("线程:{},获得锁,锁存活时间:{}S",Thread.currentThread().getName(),timeToLive/1000);

        //休眠一下

        Thread.sleep(2000);

   //设置了时间,没有watchdog机制

        //如果主线程未释放,且当前锁未调用unlock方法,则锁到期后会自动释放的

        //如果主线程未释放,且当前锁调用unlock方法,则直接释放锁

        rLock.unlock();

        log.info("线程:{},释放锁",Thread.currentThread().getName());

    }

 

 

    public void  tryLock() throws InterruptedException {

        log.info("线程:{},进入方法",Thread.currentThread().getName());

        RLock rLock = redissonClient.getLock("tryLock");

        //tryLock()方法是有返回值的,它表示用来尝试获取锁,

        //如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false .

        boolean flag = rLock.tryLock();

        if (flag){

            long timeToLive = rLock.remainTimeToLive();

            log.info("线程:{},获得锁,锁存活时间:{}S,加锁状态:{}",Thread.currentThread().getName(),timeToLive/1000,flag);

            //休眠一下

            Thread.sleep(2000);

       //一般情况下用这个也行,但是没有显示指定锁存在时间

            //如果主线程未释放,且当前锁未调用unlock方法,则进入到watchDog机制

            //如果主线程未释放,且当前锁调用unlock方法,则直接释放锁

            rLock.unlock();

            log.info("线程:{},释放锁",Thread.currentThread().getName());

        }else {

            log.info("线程:{},获得锁失败",Thread.currentThread().getName());

        }

    }

 

    public void  tryLockWaitTime() throws InterruptedException {

        log.info("线程:{},进入方法",Thread.currentThread().getName());

        RLock rLock = redissonClient.getLock("tryLockWaitTime");

        //tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的,

        //只不过区别在于这个方法在拿不到锁时会等待一定的时间,

        //在时间期限之内如果还拿不到锁,就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。

        //这里的6是如果一个线程拿锁失败会在六秒内进行重试

        boolean flag = rLock.tryLock(6, TimeUnit.SECONDS);

        if (flag){

            long timeToLive = rLock.remainTimeToLive();

            log.info("线程:{},获得锁,锁存活时间:{}S,加锁状态:{}",Thread.currentThread().getName(),timeToLive/1000,flag);

            //休眠一下

            Thread.sleep(10000);

            //如果主线程未释放,且当前锁未调用unlock方法,则进入到watchDog机制

            //如果主线程未释放,且当前锁调用unlock方法,则直接释放锁

            rLock.unlock();

            log.info("线程:{},释放锁",Thread.currentThread().getName());

        }else {

            log.info("线程:{},获得锁失败",Thread.currentThread().getName());

        }

 

    }

 

 

    public void  tryLockleasTime() throws InterruptedException {

        log.info("线程:{},进入方法",Thread.currentThread().getName());

        RLock rLock = redissonClient.getLock("tryLockleasTime");

        //比上面多一个参数,多添加一个锁的有效时间

    //锁存在10秒,在11秒内,获取锁失败的线程都会重复的去获取锁,这里第一个参数也可以设置为0,失败就不获取了。

        boolean flag = rLock.tryLock(11,10, TimeUnit.SECONDS);

        if (flag){

            long timeToLive = rLock.remainTimeToLive();

            log.info("线程:{},获得锁,锁存活时间:{}S,加锁状态:{}",Thread.currentThread().getName(),timeToLive/1000,flag);

            //休眠一下

            Thread.sleep(6000);

            //如果主线程未释放,且当前锁未调用unlock方法,则锁到期后会自动释放的

            //如果主线程未释放,且当前锁调用unlock方法,则直接释放锁

            rLock.unlock();

            log.info("线程:{},释放锁",Thread.currentThread().getName());

        }else {

            log.info("线程:{},获得锁失败",Thread.currentThread().getName());

        }

    }