zoukankan      html  css  js  c++  java
  • jvm层面锁优化+一般锁的优化策略

    偏向锁:

    首先了解对象头MARK指针(对象头标记,32位)

    存储GC标记对象年龄对象Hash锁信息(锁记录的指针,偏向锁线程的ID)

    大部分情况是没有竞争的,所以可以通过偏向来提高性能

    所谓的偏向,即锁会偏向于当前已经占有锁的线程 ,通过将对象头Mark的标记设置为偏向,并将线程ID写入对象头Mark 只要没有竞争,获得偏向锁的线程,在将来进入同步块,不需要做同步 ,当其他线程请求相同的锁时,偏向模式结束 -XX:+UseBiasedLocking 默认启用 在竞争激烈的场合,偏向锁会增加系统负担

    轻量级锁:

    普通的锁,性能方面不是很理想,轻量级锁是一种快速的锁定方法,

    如果对象没有被锁定 ,将对象头Mark指针保存到锁对象中, 将对象头设置为指向锁的指针(在栈空间中),

    如果轻量级锁失败,表示存在竞争,升级为重量级锁(常规锁)

    优势:

    减少OS互斥量(传统锁)产生的性能损耗

    缺点:

    在竞争激烈时,轻量级锁会多做很多额外操作,导致性能下降

    自旋锁:

    (1)线程竞争通常存在(2)锁持有时间较短,也就是同步快较短

    可以使用自选锁(spinning lock)

    当竞争存在时,如果线程可以很快获得锁,那么可以不在OS层挂起线程让线程做几个空操作(自旋),自旋感觉就像是轮询,如果自旋成功,可以节省线程挂机,切换时间,提升系统性能,相反,如果同步快很长,自旋失败,会降低系统性能。

    总结:

    这三种锁不是Java方面的锁优化方法

    内置于JVM中锁的优化方案:

    偏向锁可用,则偏向锁或轻量级锁可用则轻量级锁---->若都失败,则尝试自旋锁----->自旋锁失败,会尝试普通锁(使用OS互斥量在操作系统层挂起)

    锁的优化:

    减少锁的持有时间

    锁分离(可以按功能划分,只要操作互不影响,锁就可以分离,)

    减小锁粒度,提高并行成都

    锁粗化(凡事都有一个度,如果对同一个锁不停的进行请求、同步和释放,其本身也会消耗系统宝贵的资源,反而不利于性能的优化,eg:合并锁)


    concurentHashMap 通过对大数组进行分段,用多个小数组来维护一个hashMap,每当一个线程
    操作hashMap时,只对他自身的一个小数组加锁(普通的hashMap是通过对超大数组直接加锁),而其他线程可以操作这个hashMap的其他小数组,不用等待;原理就是,减小锁力度,提高并行程度

    除了通过减小锁力度,还可以通过根据功能不同进行锁分离:比如读写锁:读多写少的情况,可以提高性能,也就是读读的情况下,多线程可以直接访问,写写,读写进行锁等待

    读写锁怎么实现:当线程A去写的话,判断读锁有没有被占用,有的话,等待,没有的话,开始写入,上写锁;当线程B去读,先判断写锁有没有被占用,有的话,等待,没有的话,开始读,上读锁---------------------延伸一下,读是一个功能,写是一个功能。
    读写锁分离思想延申:即只要操作互不影响,锁就可以分离,取元素和读元素两个操作互不影响
    LinkedBlockIngQunue:take/put,内部一把tak锁,一把put锁,当take的时候,加take锁,put的时候加put锁,但是多个线程,可以同时take,put。

    所有的主动加锁,都是悲观锁,
    无锁:乐观锁,cas原理,传入新值,期待值;内部旧值和期待值相比,比如数据库(直接内存)期待一个值为x,旧值如果等于x,那么将新值设入。

    锁粗化:初衷是为了提高并行程度,减小锁粒度,但是频繁的请求,同步,释放,持有锁时间较短,造成系统频繁切换,增加额外消耗,违背初衷,此时使用锁粗化:

  • 相关阅读:
    图的应用详解-数据结构
    图的遍历
    node.js基础模块http、网页分析工具cherrio实现爬虫
    NodeJS制作爬虫全过程
    Nodejs爬虫进阶教程之异步并发控制
    asp.net的临时文件夹
    Cms WebSite 编译非常慢
    查看数据库的表被谁锁住了,以及如何解锁
    WinRar 设置默认的压缩格式为zip
    Can not Stop-Computer in powershell 6.0
  • 原文地址:https://www.cnblogs.com/brxHqs/p/9647972.html
Copyright © 2011-2022 走看看