锁、分布式锁、无锁分布式无锁

锁、分布式锁、无锁分布式无锁

 

 

为什么要有锁?

 

      保证资源线程安全,简单说就是在多线程情况下不会乱。

 

 

 

锁的分类

 

  • JVM锁:类锁、对象锁、偏向、公平、重入、死锁
  • 分布式锁:Redis、DB、zookeeper

 

 

类锁和对象锁的区别

 

类锁

 

  1. 方法中写着static synchronized
  2. 整个Object.class只有一个锁,所有对象只有一个锁

 

对象锁

 

  1. 方法声明中只写synchronized
  2. Object的实例化对象object1、object2、object3,各有一个自己的锁

 

 

 

JVM锁如何实现

 

同步方法

 

public synchronized void save(){}

 

注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类

 

 

 

同步块

 

synchronized(object){ 

}

     

注:同步是一种高开销的操作,因此应该尽量减少同步的内容。 

 

 

 

volatile

 

  1. volatile关键字为域变量的访问提供了一种免锁机制, 
  2. 使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新, 
  3. 因此每次使用该域就要重新计算,而不是使用寄存器中的值 
  4. volatile不会提供任何原子操作,它也不能用来修饰final类型的变量 

注:这个虽然能实现线程安全,但是没有原子性,如(i++)

 

 

 

重入锁:ReenreantLock

 

  1. ReentrantLock() : 创建一个ReentrantLock实例 
  2. lock() : 获得锁 
  3. unlock() : 释放锁 

注:ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用

 

 

 

并发集合、并发工具类

 

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • 并发工具类:java.util.concurrent(JUC)

 

 

原子操作:Atomic

 

 

使用局部变量实现线程同步:ThreadLocal

分布式锁

Redis

  • 单线程,速度快,单点
  • 加锁:setNx()、取锁:getNx()
  • 或者setString也可以实现分布式锁

DB

悲观锁:select * from table for update(Quartz)

乐观锁:加多个version字段

Zookeeper:待学习。。。。。

无锁、分布式无锁

同样是使用redis实现,用它的自增功能,jedis.incr()

猜你喜欢

转载自youyu4.iteye.com/blog/2413463