首先感谢 图片引用自知乎bravo1988 ,感谢分享,本片文章也是在感发之下写的。
Synchronized关键字或者renntrantLock 偏向锁、自旋锁、重量级锁或者CAS、Redis分布式锁
JVM锁出现是为了解决线程安全问题。(就是数据不一致);
线程安全问题出现的原因是:1)多线程环境,2)有共享数据,3)多条语句操作共享数据。
例如:线程A、B同时对int count进行+1操作
JVM锁,将两个线程强行排队的方式进行访问内存。所有的线程必须依次排队通过锁,这种锁的实现最常见的机制有:
synchronized关键字
cas+aqs(ReentrantLock)
synchronized加锁解锁的过程是隐式的,用户不用手动操作,优点是操作简单,但显得不够灵活。一般并发场景使用synchronized的这个关键字就够了。
但是Synchronized锁 性能比较低下,因此引入ReentrantLock 它基于CAS+AQS类似自旋锁;自旋的意思是:在发生资源竞争的是后,未争取到锁的线程会在门外采取自旋的方式等待锁的释放谁抢到谁执行。
两者原理:ReentrantLock和synchronized都是独占锁,只允许线程互斥的访问临界区。(通俗讲都是要一一排队顺序通过 ,甭想插队)
ReentrantLock需要手动加锁和解锁,且解锁的操作尽量要放在finally代码块中,保证线程正确释放锁
ReenTrantLock 好处就是不需要切换内核态申请操作系统的重量级锁,坏处:需要占用部分cpu资源,如果高并发情况下,会大量消耗cpu资源。
redis分布式锁
首先讲一下什么是分布式;
分布式是在当前高并发。多用户情况下,表现层有多个(前端服务器),服务层也有多个(后端服务器),
分布式特点就是当服务层相同程序,部署不在一个服务器中(JVM内存不同),这种JVM锁就无法保证能够互斥。
Redis分布式锁就是将锁加入表现层与服务层中间,使得所有服务线程都需要经过这个锁,起到了安全问题。
redis中的指令 setnx 就是这种情况,,当key不存在时可以设置成功返回true 否则不会重复设置
Redis 五种类型:字符串(string)列表(List),集合(set)有序集合(zset),哈希(Hash)