首页 > 编程语言 >Java中七七八八的各种锁

Java中七七八八的各种锁

时间:2023-07-17 22:11:42浏览次数:36  
标签:各种 Java synchronized StringBuffer 七七八八 获取 线程 公平 append

  1. 乐观锁 or 悲观锁
  • 乐观锁即蹲坑不锁门,只会在更新的时候判断有没有其他线程去更改数据,有的话就回滚
    典型:
  • 悲观锁即进厕所立马锁门,其他线程来了即阻塞,进到阻塞队列中,等待主线程蹲坑完毕后,按顺序获取
    典型:synchronized 和 ReentrantLock
  1. 独占锁 or 共享锁
  • 顾名思义,独占锁即获取之后,既能读数据也能写数据,其他线程无法获取锁且无法加任意类型的锁,即阻塞住了
  • 共享锁可同时被多个线程获取,但只能读数据,不能写数据
  1. 互斥锁 or 读写锁
  • 互斥锁保证了某一数据只能同时被一个线程操作,有唯一性 and 排他性
  • 读写锁:实际上为两个锁(读锁和写锁)读锁为共享锁,写锁为独占锁
  1. 公平锁 or 非公平锁
  • 公平锁指的是线程之间按照到来的先后顺序依次获取锁
  • 而非公平锁为,线程想获取锁了,无视队列,直接试图获取锁,强硬霸道,弱肉强食,弊端为有可能出现饥饿状态(即无线程成功获取到锁)
    Java中synchronized为非公平锁,ReentrantLock可设置,但默认为非公平锁
/**
* 创建一个可重入锁,true 表示公平锁,false 表示非公平锁。默认非公平锁
*/
Lock lock = new ReentrantLock(false);
  1. 可重入锁
    我之前一直以为只有Redis可以实现,现在知道了ReentrantLock(可重入锁)顾名思义,synchronized也可以实现
    好处:实现递归取锁,避免死锁,体现灵活性与可控性
  2. 自旋锁
    个人理解:尝试获取锁,获取不到的话不会直接将线程挂起,而是采取自旋操作,进入一个忙循环,循环尝试获取锁
    好处:减少线程被挂起的几率,因为线程被挂起需要耗费大量的资源,但是长时间进入忙循环会耗费比挂起更高的性能,所以不适合长时间自旋的场景
  3. 分段锁 Segment
    即更细粒度的锁,当需要进行数据操作的时候,只要对需要操作的模块加锁即可,不用对整体加锁
    CurrentHashMap底层就使用的Segment
  4. 锁升级
    即无锁 --》 偏向锁 --》轻量级锁 --》 重量级锁
  • 偏向锁:会偏向第一个访问的线程,通常在不存在多线程竞争的时候默认上这把锁,后续若访问该资源的线程过多,通过控制对象Mark Word的标志位来判断,对象头存储的线程id是否与当前线程id一致
  • 轻量级锁:竞争变得较为激烈,即升级为轻量级锁,承认线程竞争的存在,但一般压力较小,获取不到会采用自旋锁那一套
  • 重量级锁:自旋超过一定次数,即升级为重量级锁,没获取到的阻塞,去阻塞队列排队
  1. 锁优化
  • 锁粗化
    顾名思义,将多个小锁合并为一个大锁,锁范围扩大
    粗化前
private static final Object LOCK = new Object();

for(int i = 0;i < 100; i++) {
    synchronized(LOCK){
        // do some magic things
    }
}

粗化后

 synchronized(LOCK){
     for(int i = 0;i < 100; i++) {
        // do some magic things
    }
}

应该很好理解吧。。。。

  • 锁消除
    即已上锁的线程,虚拟机编译器在运行时检测到几乎没啥线程竞争了,从而将锁消除
    例子:方法test本身就为线程安全的
public String test(String s1, String s2){
    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer.append(s1);
    stringBuffer.append(s2);
    return stringBuffer.toString();
}

StringBuffer的线程安全在此场景显得有点点多余,故虚拟机自动进行了锁消除

StringBuffer.class

// append 是同步方法
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

最后,即大佬总结的神图

标签:各种,Java,synchronized,StringBuffer,七七八八,获取,线程,公平,append
From: https://www.cnblogs.com/haipali/p/17561402.html

相关文章

  • Java 变量类型
    在Java中,变量可以分为以下几种类型:变量(LocalVariables):定义在方法、构造方法或代码块内部的变量。局部变量在声明时被创建,并在方法执行完毕后被销毁。局部变量没有默认值,必须在使用前进行初始化。参数(Parameters):定义在方法或构造方法的参数列表中的变量。参数是用于接收方法......
  • Java爬虫--HttpClient-Post请求
    //下面是一个demo:packagetest;importorg.apache.http.HttpEntity;importorg.apache.http.client.methods.CloseableHttpResponse;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.util......
  • java ExecutorService 主线程不停吗
    如何实现"JavaExecutorService主线程不停"1.简介在Java中,可以使用ExecutorService来实现多线程任务的执行和管理。主线程指的是调用ExecutorService的线程,在任务执行完成之前,主线程通常是需要等待的,但有时候我们希望主线程不停止,而是继续执行其他操作。本文将介绍如何实现这......
  • java BitSet
    JavaBitSet的实现引言在Java开发中,BitSet是一个非常有用的类,用于存储和操作位集合。它可以用于各种场景,如位图索引、布隆过滤器、位掩码等。本文将介绍如何实现一个简单的JavaBitSet,并教会刚入行的开发者如何使用它。步骤概览下面是实现JavaBitSet的步骤概览,我们将一步步进......
  • java Base64 加密
    JavaBase64加密解密详解在实际应用开发中,我们经常需要对数据进行加密和解密操作。其中,Base64是一种常用的编码方式,它将二进制数据转换为可打印的ASCII字符串,使得数据可以在网络传输中进行安全的传递。本文将介绍Java中的Base64加密和解密操作,并提供相应的代码示例。Base......
  • java Array工具类构建数组
    JavaArray工具类构建数组在Java编程中,数组是一种重要的数据结构,它可以用于存储和操作一组相同类型的数据。在构建数组时,我们可以使用Java的Array工具类来帮助我们更轻松地创建和操作数组。本文将介绍如何使用JavaArray工具类来构建数组,并提供一些常用的示例代码。1.导入Array......
  • java @path
    实现Java@Path注解的步骤作为一名经验丰富的开发者,你即将向一位刚入行的小白解释如何实现Java@Path注解。这个注解用于标识RESTfulAPI中的路径。步骤概览下面是实现Java@Path注解的步骤概览,我们将通过表格的形式展示每个步骤所需的操作:步骤操作代码1.引入相关依......
  • java @Dict多个值
    Java中的@Dict多个值在Java编程中,我们经常需要处理与字典相关的数据,例如将数据库查询结果转换为可读的文字描述。在实际开发中,我们可能需要根据字典表中的多个值进行查询和转换。为了简化这一过程,我们可以使用@Dict注解来实现多个值的转换。什么是@Dict注解?@Dict注解是一种用于......
  • Java数组
    Java数组数组概述数组的定义数组是相同类型数据的有序结合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问他们数组声明创建首先必须声明数组变量,才能在程序中使用数组.下面是声明......
  • Java从零基础到架构师再到运维的学习路线
    Java从零基础到架构师再到运维的学习路线1.Java基础知识:-Java语法和基本数据类型-面向对象编程概念:类、对象、继承、封装、多态等-流程控制和循环:条件语句、循环语句-异常处理:异常类型、try-catch-finally块-集合框架:-数组:一维数组和多维数组,数组的操......