转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html 

锁的优化策略

编码过程中可采取的锁优化的思路有以下几种:

1:减少锁持有时间

例如:对一个方法加锁,不如对方法中需要同步的几行代码加锁;

2:减小锁粒度

例如:ConcurrentHashMap采取对segment加锁而不是整个map加锁,提高并发性;

3:锁分离

根据同步操作的性质,把锁划分为的读锁和写锁,读锁之间不互斥,提高了并发性。

4:锁粗化

这看起来与思路1有冲突,其实不然。思路1是针对一个线程中只有个别地方需要同步,所以把锁加在同步的语句上而不是更大的范围,减少线程持有锁的时间;

而锁粗化是指:在一个间隔性地需要执行同步语句的线程中,如果在不连续的同步块间频繁加锁解锁是很耗性能的,因此把加锁范围扩大,把这些不连续的同步语句进行一次性加锁解锁。虽然线程持有锁的时间增加了,但是总体来说是优化了的。

5:锁消除

锁消除是编译器做的事:根据代码逃逸技术,如果判断到一段代码中,堆上的数据不会逃逸出当前线程(即不会影响线程空间外的数据),那么可以认为这段代码是线程安全的,不必要加锁。

Java虚拟机中采取的锁优化策略:

1:偏向锁:锁对象偏向于当前获得它的线程,如果在接下来的没有被其他线程请求,则持有该锁的线程将不再需要进行同步操作(即:持有该锁的线程在接下来的执行中遇到同步块时不再需要lock和unlock了,直接执行即可)。当另一个线程申请该锁时,当前线程的偏向模式才会结束,让出该锁。

2:轻量级锁:syncrhoized的底层实现是通过监视器monitor来控制的,而monitorenter与monitorexit这两个原语是依赖操作系统互斥(mutex)来实现的。

互斥会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源。轻量级锁(Lightweight Locking)利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG),尝试在进入互斥前,进行补救,减少多线程进入互斥的几率。

如果偏向锁失败,那么系统会进行轻量级锁的操作,使用CAS操作来尝试加锁。如果轻量级锁失败,才调用系统级别的重量级锁(syncrhoized)来加锁。

3:自旋锁:当线程申请锁时,锁被占用,则让当前线程执行一个忙循环(自旋),看看持有锁的线程是否会很快释放锁。如果自旋后还没获得锁,才进入同步阻塞状态;

3.1:自适应自旋:自旋的线程自旋的时间为同一个锁上一次线程自旋并获得锁的耗时。如果对于这个锁,自旋很少有成功的,就不自旋了,避免浪费CPU资源。

为了尽量避免使用重量级锁(操作系统层面的互斥),JVM首先会尝试轻量级锁,轻量级锁会尝试使用CAS操作来获得锁,如果轻量级锁获得失败,说明存在竞争。但是也许很快就能获得锁,就会尝试自旋锁,将线程做几个空循环,每次循环时都不断尝试获得锁。如果自旋锁也失败,那么只能升级成重量级锁。

Java多线程之锁优化策略的更多相关文章

  1. java多线程编程——锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  2. Java多线程编程 — 锁优化

      阅读目录 一.尽量不要锁住方法 二.缩小同步代码块,只锁数据 三.锁中尽量不要再包含锁 四.将锁私有化,在内部管理锁 五.进行适当的锁分解 正文 并发环境下进行编程时,需要使用锁机制来同步多线程间 ...

  3. Java多线程编程—锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  4. JAVA多线程与锁机制

    JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...

  5. Java 多线程:锁(二)

    Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ...

  6. Java 虚拟机对锁优化所做的努力

    作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1 ...

  7. Java 多线程:锁(一)

    Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ...

  8. Java 多线程:锁(三)

    Java 多线程:锁(三) 作者:Grey 原文地址: 博客园:Java 多线程:锁(三) CSDN:Java 多线程:锁(三) StampedLock StampedLock其实是对读写锁的一种改进 ...

  9. 深入理解多线程(五)—— Java虚拟机的锁优化技术

    本文是<深入理解多线程>的第五篇文章,前面几篇文章中我们从synchronized的实现原理开始,一直介绍到了Monitor的实现原理. 前情提要 通过前面几篇文章,我们已经知道: 1.同 ...

随机推荐

  1. [Web 前端] 流行的JavaScript库 ——jQuery

    cp : https://www.cnblogs.com/zhoushihui/p/5141767.html   1.为了简化 JavaScript 的开发, 一些 JavsScript 库诞生了. ...

  2. protobuf语法简介2

    protobuf语法简介2 1.optional的字段和默认值 如上所述,消息描述中的一个元素可以被标记为"可选的"(optional).一个格式良好的消息可以包含0个或一个opt ...

  3. GDSL 1.7 发布,C语言通用数据结构库

    GDSL 1.7 修复了 interval-heap 模块的一个小 bug. GDSL (通用数据结构库) 包含一组程序用于操作各种数据结构.这是一个可移植的库,完全由 ANSI C 编写.为 C 开 ...

  4. junit5了解一下

    要求java8及以上版本 JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage https://junit.org/junit5/docs/ ...

  5. C++11 std::unique_lock与std::lock_guard区别及多线程应用实例

    C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...

  6. Windows7安装CodeTyphon

    WARNING 1: On windows (XP, Vista and Win7), you must install this software as user with administrato ...

  7. BERT深度解析

    这篇文章看起来很不错: https://blog.csdn.net/qq_39521554/article/details/83062188 仔细看看. 也可以看这个github,一样的文章: htt ...

  8. [leetcode]Maximum Subarray @ Python

    原题地址:https://oj.leetcode.com/problems/maximum-subarray/ 题意: Find the contiguous subarray within an a ...

  9. 搭建MySQL高可用负载均衡集群(转)

    阅读目录 1.简介 2.基本环境 3.配置MySQL主主复制 4.中间件简述 4.1.Haproxy介绍 4.2.keepalived介绍 5.中间件的安装与配置(haproxy.keepalived ...

  10. 转:TensorFlow入门(六) 双端 LSTM 实现序列标注(分词)

    http://blog.csdn.net/Jerr__y/article/details/70471066 欢迎转载,但请务必注明原文出处及作者信息. @author: huangyongye @cr ...