在单进程的系统中,当存在多个线程能够同时改变某个变量时,就须要对变量或代码块作同步,使其在修改这种变量时可以线性执行消除并发修改变量。
而同步的本质是经过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么须要在某个地方作个标记,这个标记必须每一个线程都能看到,当标记不存在时能够设置该标记,其他后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记。这个标记能够理解为锁。
不一样地方实现锁的方式也不同,只要能知足全部线程都能看获得标记便可。如java中synchronize是在对象头设置标记,Lock接口的实现类基本上都只是某一个volitile修饰的int型变量其保证每一个线程都能拥有对该int的可见性和原子修改,linux内核中也是利用互斥量或信号量等内存数据作标记。java
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,经常须要协调他们的动做。若是不一样的系统或是同一个系统的不一样主机之间共享了一个或一组资源,那么访问这些资源的时候,每每须要互斥来防止彼此干扰来保证一致性,在这种状况下,便须要使用到分布式锁。linux
基于数据库乐观锁实现:
乐观锁一般实现基于数据版本号(version)的记录机制实现的,在修改数据库前获取版本号,修改数据时与获取版本号不一致则抛出异常(修改数据时切记对版本号进行+1)git
使用redis的setnx()、get()、getset()方法,用于分布式锁redis
利用临时节点与 watch 机制。每一个锁占用一个普通节点 /lock,当须要获取锁时在 /lock 目录下建立一个临时节点,建立成功则表示获取锁成功,失败则 watch/lock 节点,有删除操做后再去争锁。临时节点好处在于当进程挂掉后能自动上锁的节点自动删除即取消锁spring
基于redisson实现的spring boot starter分布式锁框架,实现了可重入锁、公平锁、联锁、红锁、读写锁等经常使用锁的方式,并支持集群模式下的redis。数据库
为何推荐此项目?缓存
引入maven依赖便可使用并发
<dependency> <groupId>io.gitee.tooleek</groupId> <artifactId>lock-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency>