Java中的锁

Posted gluawwa

tags:

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

Java中锁的概念

自旋锁:为了不放弃CPU事件,循环使用CAS尝试对数据进行更新,直至成功。

悲观锁:假定会发生并发冲突,对所有操作加锁

乐观锁:假定没有冲突,在修改数据时如果发现数据与之前获取的不一致,则读取最新数据,修改后重试修改

独享锁(写):给资源加上写锁,线程可以修改资源,其他线程不能再获取锁

共享锁(读):给资源加上独锁后只能读不能写,其他线程也只能加读锁

可重入锁、不可重入锁:线程拿到锁后,可以自由进入同一把锁所同步的其他代码

公平锁、非公平锁:争抢锁的顺序,如果是按先来后到的原则,则是公平的

几种重要的锁的实现:synchronized、Reentranlock、ReenTranReadWriteLock

同步关键字synchronized

 属于最基本的线程通信机制,基于对象监视器实现的

 Java中每个对象都与一个监视器相关联,一个线程可以加锁或者解锁

 一次只有一个线程可以锁定监视器

试图锁定该监视器的任何其他线程都会被阻塞,直到它们可以获得线程上的监视器为止

特性:可重入、独享、悲观锁

范围:类锁、对象锁、锁消除、锁粗化

同步关键字,不仅是实现同步,根据JMM规定还能保证内存可见性(读取最新主内存数据,结束后写进主内存)

同步关键字加锁原理

 

当有线程对对象进行加锁操作时,会修改对象Mark Word中的内容,以下是偏向锁到轻量级锁的过程

偏向标记第一次有用,当出现争抢以后就没用了。-XX:UseBiasedLocking禁止使用偏置锁定

偏向锁,本质上是无锁,当有线程对对象加锁时,只需比对thread ID。如果没有发生过多线程争抢锁的情况,JVM就认为是单线程的,无需去做同步

重量级锁--监视器(monitor)

修改Mark Word如果失败,会自旋CAS一定次数,该次数可以通过参数配置:

超过次数,仍未抢到锁,则升级为重量级锁,进入阻塞。

monitor也叫管程。一个对象会有一个对应的monitor。

 锁降级

锁降级指的是写锁降级为读锁。把持住当前拥有的写锁的同时,再获取到读锁,最后释放写锁的过程。这里使用

ReentrantReadWriteLock中的代码示例。

/* <p><b>Sample usages</b>. Here is a code sketch showing how to perform
       lock downgrading after updating a cache (exception handling is
       particularly tricky when handling multiple locks in a non-nested
       fashion):
        */
       
class CachedData {
  Object data;
  volatile boolean cacheValid;
  final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
 
  void processCachedData() {
    rwl.readLock().lock();
    if (!cacheValid) {
      // Must release read lock before acquiring write lock
      rwl.readLock().unlock();
      rwl.writeLock().lock();
      try {
        // Recheck state because another thread might have
        // acquired write lock and changed state before we did.
        if (!cacheValid) {
          data = ...
          cacheValid = true;
        }
        // Downgrade by acquiring read lock before releasing write lock
        rwl.readLock().lock();
      } finally {
        rwl.writeLock().unlock(); // Unlock write, still hold read
      }
    }
 
    try {
      use(data);
    } finally {
      rwl.readLock().unlock();
    }
  }
}}

 

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

Java多线程——Lock&Condition

Java多线程与并发库高级应用-工具类介绍

Java多线程与并发库高级应用-工具类介绍

Java的锁

浅谈Java中的锁:Synchronized重入锁读写锁

ReentrantReadWriteLock场景应用