前言碎语
以下内容为博主准备在公司内部分享【分布式锁】相关列的提纲,全文基本都是关键字,分享过程全靠编了,尽量涵盖多线程以及锁分布式锁的各种使用技巧 和使用场景吧。
和锁相关的东西?
多线程、高并发、大流量、资源保护、并行、串行
锁的使用场景?了解了以上的和锁相关的东西后,我们大概知道了锁的使用场景,如:
多线程高并发下的资源保护,有序的消费资源
锁的分类?基于锁的使用场景的细分,有会很多不同锁
- 自旋锁
- 阻塞锁
- 读写锁
- 可重入锁
- 公平锁(非公平锁)……
- 如AtomicInteger,AtomicBoolean等Atomicxxxx原子变量
- 如ConcurrentHashMap,ConcurrentLinkedQueue等Concurrentxxxxx线程安全数据存储结构
- 如semaphore,CountDownLatch,CyclicBarrier等多线程控制类
如上的所述的在单实例的时候没点问题,基于cpu的cas(compare And Swap)控制,这些锁可以很好的解决多线程高并发下的资源抢占问题。那么,跨jvm进程的多实例呢?
redis原子操作实现分布式锁。
锁时效,锁等待,锁释放通知,锁粒度可控,JDK有的都要有,what?redis客户端redisson都已经实现的差不多了。
Redisson的部分实现细节?
public void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException { Long ttl = tryAcquire(leaseTime, unit);//获取锁 if (ttl == null) {//为空代表已拿到 return; } long threadId = Thread.currentThread().getId();//获取线程ID RFuturefuture = subscribe(threadId);//订阅锁释放通知 get(future);//阻塞等待锁释放通知 try { while (true) { ttl = tryAcquire(leaseTime, unit);//尝试拿锁 // lock acquired if (ttl == null) { break; } // waiting for message if (ttl >= 0) { getEntry(threadId).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);//使用信号量阻塞 } else { getEntry(threadId).getLatch().acquire();//释放信号 } } } finally { unsubscribe(future, threadId); } // get(lockAsync(leaseTime, unit)); }
怎么简化锁使用?
项目地址:https://gitee.com/kekingcn/spring-boot-klock-starter
项目的特点?- Spring boot组件开箱即用
- 基于注解aop,简单实用
- 锁等待,锁释放可全局,可局部灵活控制
- 使用Spel获取锁Key值,锁粒度灵活细分化
后记总结
知其然知其所以然,然后了解同样的东西不同的实现方式不同的应用场景,下次遇到类似问题便可迎刃而解。不仅多线程和分布式锁是这样,其他技术概念都一样