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

买房子最好的网站seo指搜索引擎

买房子最好的网站,seo指搜索引擎,在家做兼职哪个网站靠谱,一般企业邮箱是哪里注册最近的自己,一直都在做些老年的技术,没有啥升级,自己也快麻木了,自己该怎么说,那必须行动起来啊!~来来,我们一起增长自己的内功 分布式锁的最强实现: Redisson 1.概念 在介绍之前,我们要知道这个Redisson是啥? 难道就是Redis的son?(我第一次就这么认为的哈哈!) 事实也的确如…

最近的自己,一直都在做些老年的技术,没有啥升级,自己也快麻木了,自己该怎么说,那必须行动起来啊!~来来,我们一起增长自己的内功

分布式锁的最强实现: Redisson

1.概念

在介绍之前,我们要知道这个Redisson是啥? 难道就是Redisson?(我第一次就这么认为的哈哈!) 事实也的确如此–>看下面解释

首先来点专业点解释:

  1. RedissonIn-momery data Grid(建立在Redis基础上的java驻内存网格)(一种针对分布式的缓冲技术挺棒的!)

  2. 通讯基于Netty,面向企业级开发

  3. 提供一系列的分布式java常用对象,以及分布式服务等

    大白话:

    ​ a.就是特么封装许多分布式常用功能的分布式工具,

    ​ b.简化开发者开发,更专注于业务开发 ,而不是话大多时间的Redis上面

    ​ c.避免分布式造轮子

2.分布式锁

这玩意儿我也说下吧?就是并发业务的刚需;俗话说: 并发好不好,就看这把锁管的好不好!

有啥example呢? (有啊!骚等~ ) 我们就以Redis来写一个简单的分布式锁:~

编写一个最简单的Redis分布式锁: 采用SpringDataRedisRedisTemplate

setIfAbsent:setNx+expire

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脚本,通过Rediseval/evalsha

lua脚本代码:

脚本名称: lockDel.lua

if redis.call('get', KEYS[1]) == ARGV[1] then -- 执行删除操作return redis.call('del', KEYS[1]) else -- 不成功,返回0return 0 
end

删除java代码:

// 解锁脚本
DefaultRedisScript<Object> unlockScript = new DefaultRedisScript();
unlockScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lockDel.lua")));// 执行lua脚本解锁
redisTemplate.execute(unlockScript, Collections.singletonList(keyName), value);

写到这儿,我们也添加了lua,也能保证原子性了吧!但是你看看是不是少了啥?(哈哈,你心里是不是在说,我看出来个锤子啊!没毛病啊)

嗯嗯,那我提个醒—按照上面的思路:如果一个线程多次拿锁呢?好家伙是不是来问题了?怎么解决呢?(想没想到?都往下看吧!哈哈)

2.3可重入锁

怎么保证可重入?

首先: 我们应该明白可重入的核心:同一个线程多次获取同一把锁是许可的,不会产生死锁

嗯~道理没怎么懂,我们用Synchronized偏向锁来理解其实现思路

  1. synchronized实现重入是在JVM层面,java对象头MARK word 中含有线程ID和计数器对线程做重入判断,从而避免每次的CAS
  2. 当一个线程访问同步块并获取锁时,会在对象头栈帧锁记录里存储偏向的线程ID
  3. 这样后面此线程ID再进入和退出同步块时,就不用CAS来进行加锁和解锁啦
  4. 只需要检测MARK WORD对象头里面是否存储指向当前线程的偏向锁
    • 测试成功:线程获得锁
    • 测试失败:再测试下MARK WORD偏向锁标志是否设置为1
      • 0: 没有CAS竞争
      • 1:CAS将对象头偏向锁指向当前线程
  5. 还有一个计数器:同个线程进入则自增1,离开再减1,直到为0释放

根据上面的思路:(我们对要实现的lua脚本进行改造)

1.准备形参(执行的条件)
需要存储锁名称lockName
该锁线程ID
对应线程进入的次数: count
2.加锁(每次线程获取锁时,判断是否已经存在该锁)
不存在:设置hash的Key为线程ID,value=1设置expireTime(过期时间)返回获取锁,成功为true
存在:继续判断是否存在当前线程ID的hash key存在:线程key的value+1,重入次数加1(count++),设置expireTime不存在:返回加锁失败
3.解锁 —>每次线程来解锁时,判断是否已经存在该锁
存在:是否有该线程的ID的hash key,有则减1,没有返回解锁失败减1:判断剩余count为不为0=0: 不再需要这把锁,执行del命令删除
1.存储结构:

Redis采用HASH结构

锁名称: lock_name1`

key: thread_id (唯一键,线程ID)

value:count` (计数器)

hset  lock_name1 thread_id  1hget  lock_name1
2.计数器加减

当同一个线程获取同一把锁时,我们需要对应线程的计数器count做加减

怎么判断一个Redis的key是否存在,

我们可以用exists/hexists判断一个hash的key是否存在,

hset  lock_name1  thread_id  1 
exists/exists  lock_name1

hash的自增命令:

hincrby   lock_name1  thread_id  1
3.解锁的判断

当一把锁不再被需要了,每解锁一次,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 DefaultRedisScript<Long> lockScript;private DefaultRedisScript<Object> 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引入依赖

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version>
</dependency><!-- 另一种Spring集成starter,本章未使用 -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.13.6</version>
</dependency>

4.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.dinnco.com/news/52929.html

相关文章:

  • 网站建设英文名词太原seo计费管理
  • h5响应式网站开发成本淘宝怎么设置关键词搜索
  • 深圳专业网站设计制作电商网站项目
  • 瑶海区网站建设公司企业网站建设方案
  • 怎样创建网站以及建站流程是什么自动点击器软件
  • 网站设计培训机构写文章免费的软件
  • 可以做链接的网站深圳seo优化公司搜索引擎优化方案
  • 外贸网站做几种产品房地产网站建设
  • 要怎样做网站发到百度上面百度竞价排名机制
  • wordpress自建站邮箱电商推广联盟
  • 网站上的flash怎么做推广网页
  • 做ppt设计师哪个网站好app搜索优化
  • o2o网站建设报价淄博seo网络公司
  • 承德网站制作多少钱徐州自动seo
  • 信阳网站建设个人网站模板建站
  • wordpress 建站教程 下载武汉大学人民医院官网
  • 网站建设中其他可能的问题上海seo网站优化软件
  • 网站开发原型 图提升关键词排名seo软件
  • 福州建站模板搭建网站优化排名方案
  • 网站制作要求专业seo公司
  • 做设计的分析图网站有哪些批量关键词排名查询工具
  • 什么是电子商务网站的建设网站建设问一问公司
  • 郑州微网站制作wifi优化大师下载
  • 做相册的网站(网易做网络推广一个月的收入
  • 网络店铺的营销方法长沙seo步骤
  • 国外做旅游攻略的网站好网络广告一般是怎么收费
  • wordpress模板内容页哪个文件西安网站seo诊断
  • 网站联盟广告名词解释推广运营公司哪家好
  • 怎么建设大淘客网站店铺推广平台有哪些
  • 计算机网站开发是那个语言网站推广优化排名公司