首页 > 编程语言 >Java中的锁

Java中的锁

时间:2022-08-15 16:59:18浏览次数:53  
标签:Java 互斥 线程 自旋 共享 数据 轻量级

一、乐观锁和悲观锁

悲观锁

一个共享数据加了悲观锁,那线程每次想操作这个数据前都会假设其他线程可能也会操作这个数据,所以每次操作前都会上锁,这样其他线程想操作这个数据拿不到锁只能阻塞了。

乐观锁

乐观锁操作数据时不会上锁,在更新的时候会判断一下在此期间是否有其他线程去更新这个数据。

乐观锁可以使用版本号机制和和CAS算法实现。

使用场景

乐观锁适用于写比较少的场景,因为不用上锁、释放锁,省去了锁的开销,从而提高了吞吐量。

如果是写多读少的场景,线程间竞争激烈,使用乐观锁就会导致线程不断进行重试,这样可能还会降低了心更难,这种场景使用悲观锁就比较合适。

二、独占锁和共享锁

独占锁

锁一次只能被一个线程持有。如果一个线程对数据加上排它锁后,那么其他线程不能再对该数据加任何类型的锁。活的独占锁的线程既能读数据又能修改数据。

共享锁

锁可以被多个线程持有。如果一个线程对数据加上共享锁后,那么其他线程只能对数据在加共享锁,不能加独占锁。获得共享锁的线程只能读数据,不能修改数据

三、互斥锁和读写锁

互斥锁

独占锁的一种常规实现,是指某一资源同时指允许一个访问者对其进行访问,具有唯一性和排他性。

互斥锁一次只能一个线程拥有互斥锁,其他线程只有等待。

读写锁

共享锁的一种具体实现。读写锁管理一组锁,一个是只读的锁,一个是写锁。

读锁可以再没有写锁的时候被多个线程共同持有,而写锁是独占的。写锁的优先级要高于读锁,一个获得了读锁的线程必能能看到前一个释放的锁更新的内容。

读写锁相比于互斥锁并发程度更高,每次只有一个写线程,但是同时可以有多个线程并发读

四、公平锁和非公平锁

公平锁

多个线程按照申请锁的顺序来获取锁

非公平锁

多个线程获取锁的顺序并不是按照申请锁的顺序,在高并发环境下,有可能造成优先级翻转或者饥饿的状态。

五、可重入锁

又称为递归锁,是指同一个线程在外层方法获取了锁,在进入内层方法会自动获取锁。

六、自旋锁

线程在没有获取锁时不是被直接挂起,二十执行一个忙循环,这个忙循环就是所谓的自旋。

自旋锁的目的是为了减少线程被挂起的几率,因为现成的挂起和唤醒都是耗资源的操作。

如果锁被另一个线程占用的时间比较长,即使自旋了之后当前线程还是会被挂起,忙循环就会变成浪费系统资源的操作,反而降低了整体性能。因此自旋锁不适应锁占用时间长的并发情况。

自适应自旋锁自旋时间不在固定,由前一次在同一个锁上的自旋时间以及锁的拥有者的状态来决定。

七、锁升级

4种锁状态:无锁、偏向锁、轻量级锁、重量级锁,他会锁着多线程的竞争情况逐渐升级,但不能降级。

无锁

无锁状态其实就是上边的乐观锁

偏向锁

Java偏向锁是指他会偏向于第一个访问锁的线程,如果在运行过程中,只有一个线程访问加锁的资源,不存在多线程竞争的情况,name线程是不需要重复获取锁的,这种情况下, 就会给线程加一个偏向锁。

轻量级锁

当线程竞争变得比较激烈时,偏向锁就会升级为轻量级锁,轻量级锁认为虽然竞争是存在的,但是理想情况下竞争的情况很低,通过自旋方式等待上一个线程释放锁。

重量级锁

如果线程并发进一步加剧,线程的自旋超过了一定次数,或者一个线程持有锁,一个线程在自旋,又来了第三个线程访问时,轻量级锁就会升级为重量级锁,重量级锁会使除了此时拥有锁的线程以外的线程都阻塞。

升级到重量级锁其实就是互斥锁了,一个线程拿到锁,其他线程都会处于阻塞等待状态。

八、锁优化技术

锁粗化

将多个同步块的数量减少,并将单个同步块的作用范围扩大,本质上就是将多次上锁,解锁的请求合并为一次同步请求

锁消除

虚拟机编译器在运行时检测到了共享数据没有竞争锁,从而将这些所进行消除。

标签:Java,互斥,线程,自旋,共享,数据,轻量级
From: https://www.cnblogs.com/zmy98/p/16588837.html

相关文章

  • 【java面试题】final
    【java面试题】final final的作用final的含义是最终的修饰类:表示类不可被继承修饰方法:表示方法不可被子类重写,但是可以重载修饰变量:表示变量一旦被赋值就不......
  • java学习路线整理
    java从入门到放弃:就业学习路线Java基础HTML、CSSJavaScriptmysqlJavaWebssmMyBatisSpringSpringMVCVueSpringBootSpringClouddocker......
  • 取两个List<Object>的差集数据和交集数据 java
    List<ProjectSimpleInfoVO>projectSimpleInfoVOList=newArrayList<>();ProjectSimpleInfoVOprojectSimpleInfoVO=newProjectSimpleInfoVO();pr......
  • java.lang.IllegalStateException: getWriter() has already been called for this re
    异常出现原因是response在获取字节流之前会判断字符流是否已使用,反之获取字符流之前也会判断字节流是否已使用,若判断已使用则抛出异常getWriter()/getOutStream()hasalre......
  • JavaScript Promise
    异步编程同步(synchronous):同步按照代码顺序执行。异步(asynchronous):异步不按照代码顺序执行。JS异步操作函数往往通过回调函数来实现异步任务的结果处理。回调函数......
  • java实现word模板导出
    Xdocreport和Freemaker生成docx只使用freemaker生成简单的word文档很容易,但是当word文档需要插入动态图片,带循环数据,且含有富文本时解决起来相对比较复杂,但是使用Xdocrepo......
  • JAVA基础
    //TreeSetTreeSet<Integer>set=newTreeSet<>();intn=in.nextInt();for(inti=0;i<n;i++){set.add(in.nextInt());......
  • linux下运行一个java类
    java代码,使用了jdk的包,以及第三方jar包(user.jar)中的类,以下例子为所有文件均在同一目录下。也可以不在同一目录,执行命令时需指定绝对路径即可。importa.b.User;import......
  • Linux异常-java.io.IOException: 打开的文件过多
     异常报错如下09-Oct-201915:37:51.923严重[http-nio2-8080-Acceptor-0]org.apache.tomcat.util.net.Nio2Endpoint$Acceptor.runSocketacceptfailedjava.......
  • 【java面试题】 == 和 equals
    【java面试题】==和equals "=="比较的机制:==对比的是栈中的值基本数据类型是变量值,也就是inti=1;在栈中存放的是i=1,==比较的也是这个数值1引用类型是堆中......