当前位置: 首页 > news >正文

电子行业网站建设设计logo的小程序

电子行业网站建设,设计logo的小程序,个人网站数据库怎么做,50个优秀网站最近的自己,一直都在做些老年的技术,没有啥升级,自己也快麻木了,自己该怎么说,那必须行动起来啊!~来来,我们一起增长自己的内功 分布式锁的最强实现: Redisson 1.概念 在介绍之前,我们要知道这个Redisson是啥? 难道就是Redis的son?(我第一次就这么认为的哈哈!) 事实也的确如… 最近的自己,一直都在做些老年的技术,没有啥升级,自己也快麻木了,自己该怎么说,那必须行动起来啊!~来来,我们一起增长自己的内功 分布式锁的最强实现: Redisson 1.概念 在介绍之前,我们要知道这个Redisson是啥? 难道就是Redis的son?(我第一次就这么认为的哈哈!) 事实也的确如此–看下面解释 首先来点专业点解释: Redisson是In-momery data Grid(建立在Redis基础上的java驻内存网格)(一种针对分布式的缓冲技术挺棒的!) 通讯基于Netty,面向企业级开发 提供一系列的分布式java常用对象,以及分布式服务等 大白话: ​ a.就是特么封装许多分布式常用功能的分布式工具, ​ b.简化开发者开发,更专注于业务开发 ,而不是话大多时间的Redis上面 ​ c.避免分布式造轮子 2.分布式锁 这玩意儿我也说下吧?就是并发业务的刚需;俗话说: 并发好不好,就看这把锁管的好不好! 有啥example呢? (有啊!骚等~ ) 我们就以Redis来写一个简单的分布式锁:~ 编写一个最简单的Redis分布式锁: 采用SpringDataRedis的RedisTemplate setIfAbsent:setNxexpire 2.1加锁操作/解锁操作 // 加锁 public Boolean tryLock(String key, String value, long timeout, TimeUnit unit) {return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit); } // 解锁防止删错别人的锁以uuid为value校验是否自己的锁 public void unlock(String lockName, String uuid) {if(uuid.equals(redisTemplate.opsForValue().get(lockName)){ redisTemplate.opsForValue().del(lockName); } } // 结构 if(tryLock){// todo }finally{unlock; } 上面的代码完成锁操作,但是我们会发现无法保证原子性,一旦并发量高了,就要好家伙了!~ 咋解决呢?咋保证原子性啊?我咋知道啊!(哈哈!我们往下读,自会柳暗花明)我们引入Redis内置的语言:lua, 2.2采用lua脚本 我们使用lua的 ,将操作封装成一个lua脚本,通过Redis的eval/evalsha lua脚本代码: 脚本名称: lockDel.lua if redis.call(get, KEYS[1]) ARGV[1] then -- 执行删除操作return redis.call(del, KEYS[1]) else -- 不成功返回0return 0 end删除java代码: // 解锁脚本 DefaultRedisScriptObject unlockScript new DefaultRedisScript(); unlockScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(lockDel.lua)));// 执行lua脚本解锁 redisTemplate.execute(unlockScript, Collections.singletonList(keyName), value);写到这儿,我们也添加了lua,也能保证原子性了吧!但是你看看是不是少了啥?(哈哈,你心里是不是在说,我看出来个锤子啊!没毛病啊) 嗯嗯,那我提个醒—按照上面的思路:如果一个线程多次拿锁呢?好家伙是不是来问题了?怎么解决呢?(想没想到?都往下看吧!哈哈) 2.3可重入锁 怎么保证可重入? 首先: 我们应该明白可重入的核心:同一个线程多次获取同一把锁是许可的,不会产生死锁 嗯~道理没怎么懂,我们用Synchronized的偏向锁来理解其实现思路 synchronized实现重入是在JVM层面,java对象头MARK word 中含有线程ID和计数器对线程做重入判断,从而避免每次的CAS当一个线程访问同步块并获取锁时,会在对象头和栈帧的锁记录里存储偏向的线程ID这样后面此线程ID再进入和退出同步块时,就不用CAS来进行加锁和解锁啦只需要检测MARK WORD对象头里面是否存储指向当前线程的偏向锁 测试成功:线程获得锁测试失败:再测试下MARK WORD偏向锁标志是否设置为1 0: 没有CAS竞争1:CAS将对象头偏向锁指向当前线程 还有一个计数器:同个线程进入则自增1,离开再减1,直到为0释放 根据上面的思路:(我们对要实现的lua脚本进行改造) 1.准备形参(执行的条件) 需要存储锁名称lockName 该锁线程ID 对应线程进入的次数: count2.加锁(每次线程获取锁时,判断是否已经存在该锁) 不存在:设置hash的Key为线程ID,value1设置expireTime(过期时间)返回获取锁,成功为true 存在:继续判断是否存在当前线程ID的hash key存在:线程key的value1,重入次数加1(count),设置expireTime不存在:返回加锁失败3.解锁 —每次线程来解锁时,判断是否已经存在该锁 存在:是否有该线程的ID的hash key,有则减1,没有返回解锁失败减1后:判断剩余count为不为00: 不再需要这把锁,执行del命令删除1.存储结构: Redis采用HASH结构 锁名称: lock_name1 key: thread_id (唯一键,线程ID) value:count (计数器) hset lock_name1 thread_id 1hget lock_name12.计数器加减 当同一个线程获取同一把锁时,我们需要对应线程的计数器count做加减 怎么判断一个Redis的key是否存在, 我们可以用exists/hexists判断一个hash的key是否存在, hset lock_name1 thread_id 1 exists/exists lock_name1hash的自增命令: hincrby lock_name1 thread_id 13.解锁的判断 当一把锁不再被需要了,每解锁一次,count减1,直到为0,执行删除 最终的LUA代码 加锁lock.lua local key KEYS[1]; local threadId ARGV[1]; local releaseTime ARGV[2];-- lockname不存在 if(redis.call(exists, key) 0) thenredis.call(hset, key, threadId, 1);redis.call(expire, key, releaseTime);return 1; end;-- 当前线程已id存在 if(redis.call(hexists, key, threadId) 1) thenredis.call(hincrby, key, threadId, 1);redis.call(expire, key, releaseTime);return 1; end; return 0;解锁unlock.lua local key KEYS[1]; local threadId ARGV[1];-- lockname、threadId不存在 if (redis.call(hexists, key, threadId) 0) thenreturn nil; end;-- 计数器-1 local count redis.call(hincrby, key, threadId, -1);-- 删除lock if (count 0) thenredis.call(del, key);return nil; end;RedisLock.java: 实现分布式锁 实现功能: 互斥,可重入,防死锁 /*** description 原生redis实现分布式锁**/ Getter Setter public class RedisLock {private RedisTemplate redisTemplate;private DefaultRedisScriptLong lockScript;private DefaultRedisScriptObject unlockScript;public RedisLock(RedisTemplate redisTemplate) {this.redisTemplate redisTemplate;// 加载加锁的脚本lockScript new DefaultRedisScript();this.lockScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(lock.lua)));this.lockScript.setResultType(Long.class);// 加载释放锁的脚本unlockScript new DefaultRedisScript();this.unlockScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(unlock.lua)));}/*** 获取锁*/public String tryLock(String lockName, long releaseTime) {// 存入的线程信息的前缀String key UUID.randomUUID().toString();// 执行脚本Long result (Long) redisTemplate.execute(lockScript,Collections.singletonList(lockName),key Thread.currentThread().getId(),releaseTime);if (result ! null result.intValue() 1) {return key;} else {return null;}}/*** 解锁* param lockName* param key*/public void unlock(String lockName, String key) {redisTemplate.execute(unlockScript,Collections.singletonList(lockName),key Thread.currentThread().getId());} }上面代码,已经实现了大部分的功能,对于一般的场景都是可以从容应对了,但是(哈哈哈,最怕但是了是不?) 针对特殊场景: 1.若A进程在获取到锁的时候,因为业务操作时间太长,锁释放了,但是业务还是在执行,此刻B 进程有可以正常拿到锁进行业务操作,这时候就会出现A,B进程共享资源的问题 2.若负责存储这个分布式锁的Redis宕机,儿此时这个锁正好处于锁住状态,这时就会造成锁死的状态 那对于这种情况时,我们需要采用锁续约 锁续约:延长锁的ReleaseTime直到完成业务期望结果,本质就是不断延长锁过期时间 但是,对于当中的处理续约,性能比如锁的最大等待时间,无效的锁申请,与以及失败重试机制等等我们写到猴年马月啊!~立即推—放弃哈哈哈!! 别别别~来这时候我们就要介绍我们今天的主角:Reidsson!!(解决上面所有问题) 4.Redisson分布式锁 兵马未动,粮草先行 我们看看咋使用啊~是不是 4.1引入依赖 dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.13.6/version /dependency!-- 另一种Spring集成starter本章未使用 -- dependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.13.6/version /dependency4.2配置 Configuration public class RedissionConfig {Value(${spring.redis.host})private String redisHost;Value(${spring.redis.password})private String password;private int port 6379;Beanpublic RedissonClient getRedisson() {Config config new Config();config.useSingleServer().setAddress(redis:// redisHost : port).setPassword(password);config.setCodec(new JsonJacksonCodec());return Redisson.create(config);} }4.3启用分布式锁 简洁明了只需要一个RLock,如下面的代码所示 Resource private RedissonClient redissonClient;RLock rLock redissonClient.getLock(lockName); try {boolean isLocked rLock.tryLock(expireTime, TimeUnit.MILLISECONDS);if (isLocked) {// TODO}} catch (Exception e) {rLock.unlock();}4.4RLock 还在更…
http://www.w-s-a.com/news/216438/

相关文章:

  • 宿松网站建设推荐秒搜科技国家官方网站
  • 网站的服务器选择wordpress文章底部加分享
  • 天津专业的网站建设公司阿里云服务器 wordpress
  • 家教辅导培训网站建设中东跨境电商平台有哪些
  • 商城形式的网站需要多少钱做医药商城网站的公司吗
  • 贵阳网站设计zu97彩票创建网站
  • 网站建设与分工的论文足球世界排名
  • 网站首页添加标签如何用模板建站
  • 官方网站包括哪几个网站泰安的网站建设公司哪家好
  • 域名虚拟服务器做网站如何搭建企业网站
  • 用手机做网站服务器口碑好的常州网站建设
  • 摄影网站的设计与实现开题报告太原企业自助建站
  • 做如美团式网站要多少钱做网站怎么去文化局备案
  • 桂平市住房和城乡建设局网站网站建设与管理自考题
  • 怎么做公司网站制作凡科官方网
  • 达人设计网官方网站建筑效果图网站有哪些
  • 网站定制哪家快建筑室内设计网
  • 网站创建方案论文旅游网站的设计与制作html
  • 网站建设的数据导入导出开发小程序需要多少钱费用
  • 局网站建设进入前十名wordpress user role editor
  • 网站托管如何收费搜一下百度
  • 中国建设劳动协会网站wordpress 区块链媒体
  • 网站开源是什么意思西安做网站科技有限公司
  • 自己怎么用h5做网站肇庆seo
  • 长沙网站seo优化公司东莞企业官方网站建设
  • 网站个人备案材料北京网站推广价格
  • 百度做任务的网站电子工程网网站
  • 中介订制网站开发玉溪网站建设设计
  • 免费网站免费无遮挡手机页面设计软件
  • 网站建设需求规格说明书中山模板建站公司