zoukankan      html  css  js  c++  java
  • 多线程优化 锁升级

    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队列),前者负责做互斥,后一个用于做线程同步。

  • 相关阅读:
    3D酷炫翻牌效果
    鼠标的默认事件之oncontextmenu及其案例
    键盘事件之keyCode
    用js和jQuery分别实现选项卡功能
    js中事件的绑定与解绑:attachEvent/detachEvent、addEventListener/removeEventListener
    js中的键盘事件:onkeydown、onkeypress、onkeyup
    用javaDBF操作(读、写)DBF文件
    Linux-tar命令
    动态查询
    java中对list进行分页显示数据到页面
  • 原文地址:https://www.cnblogs.com/james111/p/7276832.html
Copyright © 2011-2022 走看看