设为首页 收藏本站
查看: 694|回复: 0

[经验分享] 使用redis来实现分布式锁

[复制链接]

尚未签到

发表于 2017-12-21 13:36:47 | 显示全部楼层 |阅读模式
public>private static final Logger LOG = LoggerFactory.getLogger(RedisDisLock.class);private transient Thread exclusiveOwnerThread;  String lockKey
="";  AtomicInteger waitToLock
=new AtomicInteger(0);public RedisDisLock(String lockKey){this.lockKey=CommonType.REDISKEY+lockKey;  }
  

public boolean tryLock(Jedis jedis) {  Thread thread
= Thread.currentThread();if(thread==this.getExclusiveOwnerThread()){return true;  }
  Long i
= jedis.setnx(lockKey, System.currentTimeMillis()+"");if(i.intValue()==1){  jedis.expire(lockKey, CommonType.LOCKEXPIRETIME);
  setExclusiveOwnerThread(thread);
return true;  }
else{//对于可能性非常低的死锁情况进行解锁  String initTime = jedis.get(lockKey);
  if(initTime==null){
  LOG.debug("initTime's value is null");
  return false;
  }
  long iniTime=0L;
  try{
  iniTime = Long.parseLong(initTime);
  }
  catch(NumberFormatException nfex){
  LOG.warn(nfex.getMessage());
  jedis.expire(lockKey, 1);
  return false;
  }
  if(((System.currentTimeMillis()-iniTime)/1000-CommonType.LOCKEXPIRETIME-1)>0){
  String oldTime = jedis.getSet(lockKey, System.currentTimeMillis()+"");//对于及其极端的情况,lock被线程1处理掉了,但是又被线程2getset新的值了,通过下一次调用trylock()方法处理
  if(oldTime==null){
  LOG.info("oldTime is null");
  return false;
  }
  if(initTime.equals(oldTime)){
  release(jedis);
  }
  }
  }
  return false;
  }
  

  public boolean tryLock(long timeout, TimeUnit unit,Jedis jedis) throws InterruptedException {
  long nanosTimeout = unit.toNanos(timeout);
  long lastTime = System.nanoTime();
  if(tryLock(jedis)){
  return true;
  }
  try{
  int waitLockers = waitToLock.getAndIncrement();
  if(waitLockers>=CommonType.WAITLOCKERS){
  LOG.debug("wait the lock' thread num is much,so return flase");
  return false;
  }
  for(;;){
  if(tryLock(jedis)){
  return true;
  }
  if (nanosTimeout <= 0){
  LOG.debug("getlock timeout");
  return false;
  }
  if(nanosTimeout>100000){
  LockSupport.parkNanos(100000);//中断100毫秒
  
                }
  long now = System.nanoTime();
  nanosTimeout -= now - lastTime;
  lastTime = now;
  if (nanosTimeout <= 0){
  LOG.debug("getlock timeout");
  return false;
  }
  if (Thread.interrupted()){
  throw new InterruptedException();
  }
  }
  }
  finally{
  waitToLock.decrementAndGet();
  }
  }
  

  public void unlock(Jedis jedis) {
  Thread thread = Thread.currentThread();
  if(thread==this.getExclusiveOwnerThread()){
  LOG.debug("unlock the thread {}",thread.getId());
  release(jedis);
  }
  }

  private void>  setExclusiveOwnerThread(null);
  jedis.del(lockKey);
  }
  /**
  * Sets the thread that currently owns exclusive access. A
  * <tt>null</tt> argument indicates that no thread owns access.
  * This method does not otherwise impose any synchronization or
  * <tt>volatile</tt> field accesses.
  */
  protected final void setExclusiveOwnerThread(Thread t) {
  exclusiveOwnerThread = t;
  }
  

  /**
  * Returns the thread last set by
  * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never
  * set.  This method does not otherwise impose any synchronization
  * or <tt>volatile</tt> field accesses.
  * @return the owner thread
  */
  protected final Thread getExclusiveOwnerThread() {
  return exclusiveOwnerThread;
  }
  
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-426447-1-1.html 上篇帖子: redis可视化客户端工具 下篇帖子: Redis主从加Sentinel模式部署
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表