redis【锁】

本贴最后更新于 1537 天前,其中的信息可能已经斗转星移

工具类

RedisLockHandler.java

package com.bohee.module.gl.voucher.redisCommon.lock; import com.alibaba.excel.util.CollectionUtils; import com.bohee.module.gl.voucher.entity.Voucher; import com.bohee.module.gl.voucher.redisCommon.redisUtils.JedisClientPools; import com.bohee.utils.common.LoggerUtils; import com.bohee.utils.common.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.Pipeline; import redis.clients.jedis.exceptions.JedisConnectionException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; /** * @author hax redis锁实现高并发 * Created by Administrator on 2020/9/4. */ @Component public class RedisLockHandler { private static final Logger LOGGER = LoggerFactory.getLogger(RedisLockHandler.class); private static final int DEFAULT_SINGLE_EXPIRE_TIME = 3; private static final int DEFAULT_BATCH_EXPIRE_TIME = 6; private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; @Autowired private JedisClientPools jedisClientPool; /** * 获取锁 如果锁可用 立即返回true, 否则返回false * @param billIdentify * @return */ public boolean tryLock(TSuperclass billIdentify) { return tryLock(billIdentify, 0L, null); } public void lock(TSuperclass billIdentify) { this.voidLock(billIdentify); } /** * 锁在给定的等待时间内空闲,则获取锁成功 返回true, 否则返回false * @param billIdentify * @param timeout * @param unit * @return */ public boolean tryLock(TSuperclass billIdentify, long timeout, TimeUnit unit) { String $_lockKey = (String) billIdentify.getTSuperclassKey(); try { String $_lockValue= StringUtils.uuid(); long nano = System.nanoTime(); do { LOGGER.debug("try lock key: " + $_lockKey); Long i = jedisClientPool.setnx($_lockKey, $_lockValue); if (i == 1) { jedisClientPool.expire($_lockKey, DEFAULT_SINGLE_EXPIRE_TIME); LOGGER.debug("get lock, key: " + $_lockKey + " , expire in " + DEFAULT_SINGLE_EXPIRE_TIME + " seconds."); return Boolean.TRUE; } else { // 存在锁 if (LOGGER.isDebugEnabled()) { String desc = jedisClientPool.get($_lockKey); LOGGER.debug("key: " + $_lockKey + " locked by another business:" + desc); } } if (timeout == 0) { break; } Thread.sleep(300); } while ((System.nanoTime() - nano) < unit.toNanos(timeout)); return Boolean.FALSE; } catch (JedisConnectionException je) { LOGGER.error(je.getMessage(), je); returnBrokenResource(jedisClientPool.getJedis()); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } finally { returnResource(jedisClientPool.getJedis()); } return Boolean.FALSE; } /** * 如果锁空闲立即返回 获取失败 一直等待 * @param billIdentify */ public void voidLock(TSuperclass billIdentify) { String key = (String) billIdentify.getTSuperclassKey(); try { do { LOGGER.info("lock key: " + key); Long i = jedisClientPool.setnx(key, key); if (i == 1) { jedisClientPool.expire(key, DEFAULT_SINGLE_EXPIRE_TIME); LOGGER.info("get lock, key: " + key + " , expire in " + DEFAULT_SINGLE_EXPIRE_TIME + " seconds."); return; } else { if (LOGGER.isDebugEnabled()) { String desc = jedisClientPool.get(key); LOGGER.info("key: " + key + " locked by another business:" + desc); } } Thread.sleep(300); } while (true); } catch (JedisConnectionException je) { LOGGER.error(je.getMessage(), je); returnBrokenResource(jedisClientPool.getJedis()); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } finally { returnResource(jedisClientPool.getJedis()); } } /** * 释放锁 * @param billIdentify */ public void unLock(TSuperclass billIdentify) { List<TSuperclass> list = new ArrayList<TSuperclass>(); list.add(billIdentify); unLock(list); } /** * 获取所有的锁数据 * @param ids * @return */ public List<TSuperclass> queryLocks(List<String> ids) { List<TSuperclass> list=new ArrayList<>(); ids.forEach(id->{ list.add(TSuperclass.getVoucher(id)); }); return list; } /** * 一键释放锁 * @param ids * @return */ public boolean unLocks(List<String> ids) { List<TSuperclass> list = this.queryLocks(ids); boolean lock = this.tryLock(list); return lock; } /** * 批量获取锁 如果全部获取 立即返回true, 部分获取失败 返回false * @param billIdentifyList * @return */ public boolean tryLock(List<TSuperclass> billIdentifyList) { return tryLock(billIdentifyList, 0L, null); } /** * 锁在给定的等待时间内空闲,则获取锁成功 返回true, 否则返回false * @param billIdentifyList * @param timeout * @param unit * @return */ public boolean tryLock(List<TSuperclass> billIdentifyList, long timeout, TimeUnit unit) { try { List<String> needLocking = new CopyOnWriteArrayList<String>(); List<String> locked = new CopyOnWriteArrayList<String>(); long nano = System.nanoTime(); do { // 构建pipeline,批量提交 Pipeline pipeline = jedisClientPool.getJedis().pipelined(); for (TSuperclass identify : billIdentifyList) { String key = (String) identify.getTSuperclassKey(); needLocking.add(key); pipeline.setnx(key, key); } LOGGER.debug("try lock keys: " + needLocking); // 提交redis执行计数 List<Object> results = pipeline.syncAndReturnAll(); for (int i = 0; i < results.size(); ++i) { Long result = (Long) results.get(i); String key = needLocking.get(i); if (result == 1) { // setnx成功,获得锁 jedisClientPool.expire(key, DEFAULT_BATCH_EXPIRE_TIME); locked.add(key); } } needLocking.removeAll(locked); // 已锁定资源去除 if (CollectionUtils.isEmpty(needLocking)) { return true; } else { // 部分资源未能锁住 LOGGER.debug("keys: " + needLocking + " locked by another business:"); } if (timeout == 0) { break; } Thread.sleep(500); } while ((System.nanoTime() - nano) < unit.toNanos(timeout)); // 得不到锁,释放锁定的部分对象,并返回失败 if (!CollectionUtils.isEmpty(locked)) { jedisClientPool.delbath(locked.toArray(new String[0])); } return false; } catch (JedisConnectionException je) { LOGGER.error(je.getMessage(), je); returnBrokenResource(jedisClientPool.getJedis()); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } finally { returnResource(jedisClientPool.getJedis()); } return true; } /** * 批量释放锁 * @param billIdentifyList */ public void unLock(List<TSuperclass> billIdentifyList) { List<String> keys = new CopyOnWriteArrayList<String>(); for (TSuperclass identify : billIdentifyList) { String key = (String) identify.getTSuperclassKey(); keys.add(key); } try { jedisClientPool.delbath(keys.toArray(new String[0])); LOGGER.debug("release lock, keys :" + keys); } catch (JedisConnectionException je) { LOGGER.error(je.getMessage(), je); returnBrokenResource(jedisClientPool.getJedis()); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } finally { returnResource(jedisClientPool.getJedis()); } } /** * 销毁连接 * @param jedis */ private void returnBrokenResource(Jedis jedis) { if (jedis == null) { return; } try { //容错 jedisClientPool.getJedisPool().returnBrokenResource(jedis); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } /** * @param jedis */ private void returnResource(Jedis jedis) { if (jedis == null) { return; } try { jedisClientPool.getJedisPool().returnResource(jedis); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } }

持续更新中..........

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8216 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 184 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 694 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 577 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 616 关注
  • RemNote
    2 引用 • 16 回帖 • 20 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 6 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 58 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    499 引用 • 1395 回帖 • 245 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 224 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    171 引用 • 1537 回帖
  • Visio
    1 引用 • 2 回帖
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    1 引用 • 28 回帖 • 1 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 26 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 99 回帖 • 1 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 4 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    188 引用 • 319 回帖 • 241 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 3 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 158 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    186 引用 • 1020 回帖
  • CodeMirror
    2 引用 • 17 回帖 • 167 关注
  • 996
    13 引用 • 200 回帖 • 3 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 7 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 2 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 558 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖 • 3 关注