zoukankan      html  css  js  c++  java
  • 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();
        }
      }
    }}
  • 相关阅读:
    javac 小记
    安全专家的工具箱
    MyBatis 缓存机制(十三)
    SpringMVC 环境搭建
    MyBatis 模糊查询的 4 种实现方式
    MyBatis 项目开发中是基于 XML 还是注解?
    MyBatis 动态 SQL 语句中出现 '<' 的问题
    数据库设计的三大范式
    mybatis 同时使用 XML 和注解
    数据库事务
  • 原文地址:https://www.cnblogs.com/wkzhao/p/10231005.html
Copyright © 2011-2022 走看看