Java并发编程——锁

Posted jet-strong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发编程——锁相关的知识,希望对你有一定的参考价值。

1、锁的作用

  Java中的锁主要用于保障多并发线程情况下数据的一致性。

  在多线程编程中为了保障数据的一致性,通常需要在使用对象或者方法之前加锁,这时如果有其他线程也需要使用该对象或方法。则首先要获得锁,如果某个线程发现锁正在被其他线程使用,就会进入阻塞队列等待锁的释放,直到其他线程执行完成并释放锁,该线程才有机会再次获取锁进行操作。

 

2、乐观锁

  乐观锁采用乐观的思想处理数据,在每次读取数据时都认为别人不会修改该数据,所以不会上锁,但在更新时会判断在此期间别人有没有更新该数据。

  通常采用在写时先读出当前版本号然后加锁的方法。具体过程为:比较当前版本号与上次的版本号,如果版本号一致,则更新,如果不一致,则重复进行读、比较、写操作。

  Java中的乐观锁是通过CAS(比较和交换)操作实现的。

  CAS是一种原子更新操作,在对数据操作之前会比较当前值跟传入的值是否一样,如果一样则更新,否则不执行更新操作,直接返回失败状态。

 

3、悲观锁

  悲观锁采用悲观思想处理数据,在每次读取数据时都认为别人会修改数据,所以每次在读取数据时都会上锁,别的线程想读写数据时就会阻塞、等待直到拿到锁。

  Java中的悲观锁大部分基于AQS(抽象的队列同步器)架构实现。该框架下的锁会先尝试以CAS乐观锁去获取锁,如果获取不到,则会转为悲观锁。许多同步类的实现都依赖于AQS,例如Synchronized、ReentrantLock、CountDownLatch、Semaphore等。

 

4、自旋锁

  如果持有锁的线程能在很短的时间内释放锁的资源,那么那些等待竞争锁的线程就不需要做内核态和用户态的切换进入阻塞、挂起状态,只需要等一等(自旋),等待持有锁的线程释放锁后即可获得锁,避免了用户线程在内核状态的切换上导致的锁时间消耗。

4.1  自旋锁的优缺点

  • 优点:自旋锁可以减少CPU上下文的切换,对于占用锁的时间非常短或锁竞争不激烈的代码块来说性能大幅度提升。
  • 缺点:在持有锁的线程占用锁时间过长或锁竞争过于激烈时,线程在自旋过程中会长时间的得不到锁资源,将引起CPU的浪费。

4.2  自旋锁的时间阈值

  JDK不同的版本所采用的自旋周期不同,JDK1.5为固定的时间,JDK1.6引入适应性自旋锁(不再是固定值)。适应性自旋锁的自旋时间是由上一次在同一个锁上的自旋时间及锁的拥有着的状态来决定的。一般为一个线程上下文切换的时间。

 

5、synchronized

  synchronized关键字用于Java 对象、方法、代码块提供线程安全的操作。synchronized属于独占锁、悲观锁、可重入锁。

  在使用synchronized修饰对象时,同一时刻只能有一个线程对该对象进行访问;在synchronized修饰方法、代码块时,同一时刻只能有一个线程执行该方法或代码块,其他线程只有等待当前线程执行完毕并释放锁资源后才能访问该对象或执行代码块。

5.1  synchronized的作用范围

  • synchronized作用于成员变量和非静态方法时,锁住的是对象的实例,即this对象。
  • synchronized作用于静态方法时,锁住的是Class实例,因为静态方法属于Class而不属于对象。
  • synchronized作用于一个代码块时,锁住的是所有代码中的配置对象。

5.2  synchronized的实现原理

  synchronized内部包含6个区域:ContentionList、EntryList、WaitSet、OnDeck、Owner、!Owner。

  • ContentionList:锁竞争队列,所有请求锁的线程都被放在竞争队列中。
  • EntryList:竞争候选列表,在ContentionList中有资格成为候选者来竞争锁资源的线程被移动到EntryList中。
  • WaitSet:等待集合,调用wait方法后被阻塞的线程将被放在WaitSet中。
  • OnDeck:竞争候选者,在同一时刻最多只有一个线程在竞争锁资源,该线程的状态被称为OnDeck。
  • Owner:竞争到锁资源的线程被称为Owner状态线程。
  • !Owner:在Owner线程释放锁后,会从Owner的状态变成!Owner。

 

以上是关于Java并发编程——锁的主要内容,如果未能解决你的问题,请参考以下文章

java并发编程常见锁类型

Java并发编程系列之十六:Lock锁

Java并发多线程编程——锁

Java并发编程——锁

Java 并发编程:核心理论

Java并发编程