lockout(在汽车上,LOCK是什么意思
发布时间: 2023-07-07

本文目录

在汽车上,LOCK是什么意思

LOCK的意思指的是锁止档,也是钥匙插入和拔出的位置。

在汽车的钥匙孔上有四个空位,分别是 LOCK档、ACC档、ON档和START档。在启动汽车时,都习惯插上钥匙后就一拧到底直接点火 ,表面看上去好像很潇洒,但实际上却很伤车,而这四个档位的作用能一步步启动汽车系统。

1、LOCK档指的是锁止档,也是钥匙插入和拔出的位置;

2、ACC档就是附件通电档,当钥匙拧到这个位置时,附件用电路就会接通;

3、ON档就是接通档,当钥匙在这个位置时,全车电路都会接通,系统就会开始做必要的准备工作和自检工作,而且在车辆正常行驶时钥匙也是保持在这个位置;

4、START档指的是启动档,将钥匙拧到此位置时,启动机电路接通,会带动发动机运转并启动。

Lock和synchronized该如何选择

synchronized和lock比较浅析

synchronized是基于jvm底层实现的数据同步,lock是基于Java编写,主要通过硬件依赖CPU指令实现数据同步。下面一一介绍

一、synchronized的实现方案

  1.synchronized能够把任何一个非null对象当成锁,实现由两种方式:

  a.当synchronized作用于非静态方法时,锁住的是当前对象的事例,当synchronized作用于静态方法时,锁住的是class实例,又因为Class的相关数据存储在永久带,因此静态方法锁相当于类的一个全局锁。

  b.当synchronized作用于一个对象实例时,锁住的是对应的代码块。

  2.synchronized锁又称为对象监视器(object)。 3.当多个线程一起访问某个对象监视器的时候,对象监视器会将这些请求存储在不同的容器中。

  》Contention List:竞争队列,所有请求锁的线程首先被放在这个竞争队列中

  》Entry List:Contention List中那些有资格成为候选资源的线程被移动到Entry List中

  》Wait Set:哪些调用wait方法被阻塞的线程被放置在这里

  》OnDeck:任意时刻,最多只有一个线程正在竞争锁资源,该线程被成为OnDeck

  》Owner:当前已经获取到所资源的线程被称为Owner

  》 !Owner:当前释放锁的线程

  下图展示了他们之前的关系

  4.synchronized在jdk1.6之后提供了多种优化方案:

  》自旋锁

    jdk1.6之后默认开启,可以使用参数-XX:+UseSpinning控制,自旋等待不能代替阻塞,且先不说对处理器数量的要求,自旋等待本身虽然避免了线程切换的开销,但它是要占用处理器时间的,因此,如果锁被占用的时间很短,自旋等待的效果就会非常好,反之,如果锁被占用的时候很长,那么自旋的线程只会白白消耗处理器资源,而不会做任何有用的工作,反而会带来性能上的浪费。自旋次数的默认值是 10 次,用户可以使用参数 -XX:PreBlockSpin 来更改。

    自旋锁的本质:执行几个空方法,稍微等一等,也许是一段时间的循环,也许是几行空的汇编指令。

  》锁消除

    即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除,依据来源于逃逸分析的数据支持,那么是什么是逃逸分析?对于虚拟机来说需要使用数据流分析来确定是否消除变量底层框架的同步代码,因为有许多同步的代码不是自己写的。

例1.1

public static String concatString(String s1, String s2, String s3) { return s1 + s2 + s3; }

  由于 String 是一个不可变的类,对字符串的连接操作总是通过生成新的 String 对象来进行的,因此 Javac 编译器会对 String 连接做自动优化。在 JDK 1.5 之前,会转化为 StringBuffer 对象的连续 append() 操作,在 JDK 1.5 及以后的版本中,会转化为 StringBuilder 对象的连续 append() 操作,这里的stringBuilder.append是线程不同步的(假设是同步)。

  Javac 转化后的字符串连接代码为:

public static String concatString(String s1, String s2, String s3) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); sb.append(s3); return sb.toString(); }

  此时的锁对象就是sb,虚拟机观察变量 sb,很快就会发现它的动态作用域被限制在 concatString() 方法内部。也就是说,sb 的所有引用永远不会 “逃逸” 到concatString() 方法之外,其他线程无法访问到它,虽然这里有锁,但是可以被安全地消除掉,在即时编译之后,这段代码就会忽略掉所有的同步而直接执行了。

  》锁粗化

  将同步块的作用范围限制得尽量小——只在共享数据的实际作用域中才进行同步,这样是为了使得需要同步的操作数量尽可能变小,如果存在锁竞争,那等待锁的线程也能尽快拿到锁。

  》轻量级锁

  加锁过程:在代码进入同步块的时候,如果此同步对象没有被锁定(锁标志位为 “01” 状态)虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的 Mark Word 的拷贝,这时候线程堆栈与对象头的状态如图 13-3 所示

   

  然后,虚拟机将使用 CAS 操作尝试将对象的 Mark Word 更新为指向 Lock Record 的指针。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象 Mark Word 的锁标志位 (Mark Word 的最后 2bit)将转变为 “00”,即表示此对象处于轻量级锁定状态,这时线程堆栈与对象头的状态如图13-4  

  如果上述更新操作失败,则说明这个锁对象被其他锁占用,此时轻量级变为重量级锁,标志位为“10”,后面等待的线程进入阻塞状态。

  解锁过程:也是由CAS进行操作的,如果对象的 Mark Word 仍然指向着线程的锁记录,那就用 CAS 操作把对象当前的 Mark Word 和线程中复制的 Displaced Mark Word 替换回来,如果替换成功,整个同步过程就完成了。如果替换失败,说明有其他线程尝试过获取该锁,那就要释放锁的同时,唤醒被挂起的线程。

  轻量级锁能提升程序同步性能的依据是 “对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。如果没有竞争,轻量级锁使用 CAS 操作避免了使用互斥量的开销,但如果存在锁竞争,除了互斥量的开销外,还额外发生了 CAS 操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。

  》偏向锁

  偏向锁也是 JDK 1.6 中引入的一项锁优化,它的目的是消除数据在无竞争情况下的同步原语,进一步提高程序的运行性能。如果说轻量级锁是在无竞争的情况下使用 CAS 操作去消除同步使用的互斥量,那偏向锁就是在无竞争的情况下把整个同步都消除掉,连 CAS 操作都不做了。

  实质就是设置一个变量,判断这个变量是否是当前线程,是就避免再次加锁解锁操作,从而避免了多次的CAS操作。坏处是如果一个线程持有偏向锁,另外一个线程想争用偏向对象,拥有者想释放这个偏向锁,

微信