锁?分布式?分布式锁?Redis实现的分布式锁
什么是锁?什么是分布式?什么是分布式锁?
锁
-
单进程的系统中,存在多个线程可以同时修改某个变量(可变共享变量)时,就需要对变量和代码块做同步,消除因为多线程导致的修改变量引发的脏数据
-
同步的本质是通过锁来实现的,为了实现多线程访问时只有一个线程可以访问执行。就需要标记,这个标记的作用就是对每个线程可见,而且每个线程在没有该标记可以添加标记。同时已经进入该标记的线程可以在执行结束之后释放该标记
-
Java 中 synchronize 是在对象头设置标记,Lock 接口的实现类基本上都只是某一个 volitile 修饰的 int 型变量其保证每个线程都能拥有对该 int 的可见性和原子性修改
分布式
CAP定律 这个定理的内容是指的是在一个分布式系统中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
这个是经典的分布式理论,在分布式场景下我们数据一致性往往是一个重要的话题,我们往往会需要满足其中的两个做出取舍,一般情况下我们最后考虑数据的最终一致性
分布式场景:应用系统集群的Session共享 应用系统的服务化拆分 底层数据库压力分摊
分布式锁
为了防止分布式系统中多个进程之间的相互干扰,我们需要一种分布式协调技术来对这些进程进行调度,分布式的协调制度就是分布式锁
分布式锁的实现
Redis实现的setnx()实现此命令是原子操作,只有在key不存在的情况下,可以set成功
ZooKeeper实现利用 Zookeeper 的顺序临时节点,来实现分布式锁和等待队列。
基于数据库的锁 利用数据库主键唯一性
Redis实现的分布式锁
(```)
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/**
* @description: 分布式锁
* @author: weipan
* @create: 2018/08/08 16:05:14
**/
@Component
public class DistributedLock {
@Autowired
@Qualifier("redisTrafficTemplate")
private RedisTemplate<String, String> tool;
//获取锁
public boolean getLock(String source, long l, TimeUnit timeUnit) {
SessionCallback sc = new SessionCallback() {
@Override
//函数式接口 可以使用Lambda操作
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.watch(source);//开始观察资源
boolean flag = null == operations.opsForValue().get(source);//资源是否可用
List<Object> rs = null;
if (flag) {//资源可用
operations.multi();//开启事务
operations.opsForValue().get(source);//必要的查询
//占用资源
//并设置其值为l timeUnit的过期时间
operations.opsForValue()
.set(source, Thread.currentThread().getName(), l, timeUnit);
rs = operations.exec();
}
return rs;
}
};
List<Object> result = (List<Object>) tool.execute(sc);
return !CollectionUtils.isEmpty(result);
}
}
(```)

浙公网安备 33010602011771号