博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程优化 锁升级
阅读量:4671 次
发布时间:2019-06-09

本文共 1980 字,大约阅读时间需要 6 分钟。

monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现的(系统调用)。互斥是一种会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源的操作。

JDK1.6对线程进行了优化,目的就是减少多线程编程下对锁竞争产生的性能开销。

 

1.无锁状态:没有加任何锁

 

2.偏向锁:如果程序中只有一个线程在访问对象,那么这个对象的锁就会偏向于这一个线程,之后一系列的原子操作都不会产生同步开销,直到其他线程在竞争锁的时候,偏向锁才会解除掉

Essentially, if your objects are locked only by one thread, the VM can make an optimization and "bias" that object to that thread in such a way that subsequent atomic operations on the object incurs no synchronization cost. I suppose this is typically geared towards overly conservative code that performs locks on objects without ever exposing them to another thread. The actual synchronization overhead will only kick in once another thread tries to obtain a lock on the object.

It is on by default in Java 6:

-XX:+UseBiasedLocking Enables a technique for improving the performance of uncontended synchronization. An object is "biased" toward the thread which first acquires its monitor via a monitorenter bytecode or synchronized method invocation; subsequent monitor-related operations performed by that thread are relatively much faster on multiprocessor machines. Some applications with significant amounts of uncontended synchronization may attain significant speedups with this flag enabled;

 

3.轻量级锁(Lightweight Locking):多个线程会去竞争锁,但是尽可能地减少多线程进入互斥的几率。它并不是要替代互斥,因为随着竞争越来越激烈,它最后也会升级成重量级锁(inflated 膨胀)

乐观锁:多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起(适应性自旋:不要旋转太久,否则会消耗过多的cpu),而是被告知这次竞争中失败,并可以再次尝试。乐观锁就是轻量级锁,悲观锁就是重量级锁。

轻量级锁是如何实现的呢?利用了CPU原语CompareAndSwap(汇编指令为CMPXCHG),尝试在进入互斥前,进行补救。

 

轻量级锁加锁(竞争的线程不会阻塞,提高了程序的响应速度)

线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,则自旋获取锁,当自旋获取锁仍然失败时,表示存在其他线程竞争锁(两条或两条以上的线程竞争同一个锁),则轻量级锁会膨胀成重量级锁。

 

 

重量级锁:重量锁又叫对象监视器(Monitor),它实际上是利用操作系统中的Mutex,除了具备Mutex互斥的功能,它还负责实现Semaphore的功能,也就是说它至少包含一个竞争锁的队列,和一个信号阻塞队列(wait队列),前者负责做互斥,后一个用于做线程同步。

转载于:https://www.cnblogs.com/james111/p/7276832.html

你可能感兴趣的文章
关于自关联1
查看>>
存储控制器、MMU、flash控制器介绍
查看>>
hdu-1814(2-sat)
查看>>
自我反省
查看>>
反射,得到Type引用的三种方式
查看>>
pl sql练习(2)
查看>>
Problem B: 判断回文字符串
查看>>
谷歌浏览器,添加默认搜索引擎的搜索地址
查看>>
数据结构化与保存
查看>>
C# .net 获取程序运行的路径的几种方法
查看>>
为什么需要Docker?
查看>>
国内5家云服务厂商 HTTPS 安全性测试横向对比
查看>>
how to control project
查看>>
转 python新手容易犯的6个错误
查看>>
第四节 -- 列表
查看>>
Python入门学习笔记4:他人的博客及他人的学习思路
查看>>
webstorm里直接调用命令行
查看>>
关联规则算法之FP growth算法
查看>>
对数组序列进行洗牌
查看>>
决策树
查看>>