使用乐观锁能够在不上锁的情况下实现线程安全,常用的实现方式就是使用CAS自旋的形式实现。
通常在分布式系统中有三种实现方式
数据库行级锁
Zookeeper实现分布锁
Redis实现乐观锁
三种方式各有优点,其中Redis和Zookeeper最常用,Redis性能最高,Zookeeper可靠性最高
代码实现基于RedisTemplate,封装使用,通过IOC控制的方式实现:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; @Component public class RedisTemplateUtil { // 锁名称 prefix expire 锁对象 public static final String LOCK_PREFIX = "RedisLock"; // 加锁失效时间,毫秒,通常是业务执行时间的3-5倍 public static final int LOCK_EXPIRE = 2000; // 轮询次数 根据项目而定 public static final int COUNT = 20; // 轮询间隔时间 一般在50-100ms,根据项目而定 public static final int INTERVAL = 50; @Autowired private RedisTemplate redisTemplate; public Boolean setLock(String key) { return redisTemplate.opsForValue().setIfAbsent(key, LOCK_PREFIX, LOCK_EXPIRE, TimeUnit.MILLISECONDS); } public Boolean deleteLock(String key) { return redisTemplate.delete(key); } public Boolean tryCasLock(String key) { int count = COUNT;//获取总轮询次数 while (count > 0) { count--; if (setLock(key)) { return true; } else { try { Thread.sleep(INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); throw new RuntimeException(false, StatusCode.ERROR, "服务器繁忙,请稍后再试。"); } } } //如果一直没有取得锁,就返回false return false; } }
使用:调用tryCasLock上锁,deleteLock解锁,解锁 *** 作放在finnally
@Service public class OrderServiceImpl implements OrderService { //分布式锁 @Autowired private RedisTemplateUtil redisLockUtils; @Override public void add() { //分布式锁,解决超额抢单问题 long start = System.currentTimeMillis(); if (redisLockUtils.tryCasLock(courseId + "")) { try{ } finally { //释放锁 redisLockUtils.deleteLock(courseId + ""); } } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)