首页 > 编程语言 >java锁的问题速通

java锁的问题速通

时间:2024-10-19 21:48:00浏览次数:9  
标签:java 速通 synchronized lock 问题 flag 线程 内存

 

1.syncronized底层原理——悲观锁

synchronized有对象锁和类锁两种,多个线程中只有一个线程可以获取对象锁,其他线程都会处于阻塞状态

synchronized是底层是基于monitor实现的。monitor是C++编写的jvm对象,主要分为owner(这个只会存一个线程的信息,记录当前锁被哪个线程获取了)、entrySet(这个是一个队列,记录没有抢到锁的线程,他们都是处于block状态的)、waitSet(记录调用了wait方法的线程)

monitor属于重量级锁,在jdk1.6之后又引入了偏向锁和轻量级锁

(更难的听不懂了,涉及JVM)

 

2.谈谈JMM(java memory model)java内存模型

JMM定义共享内存中,多线程程序的读写规范。JMM把内存分为工作内存和主内存;线程和线程之间是隔离的,但是可以通过线程1把消息从工作内存发送给主内存,再由主内存把消息推送给线程2,实现线程之间的交互

个人理解工作内存≈栈内存Stack,而主内存≈堆内存Heap

 

3.谈谈CAS(compare and swap)——乐观锁 | 自旋锁

cas是一种乐观锁思想,在无锁情况下保证线程操作共享数据的原子性。

java中的cas是基于操作系统的cas实现的,属于native方法;工作内存从主内存读取到的数据,我们需要把旧数据修改。当要修改时我们会再次比对工作内存的旧数据和主内存的数据,如果一致,那么就可以修改;如果不一致,那就要发生自旋:工作内存再次去主内存读取数据并重复上述方法。

在锁竞争不激烈的情况下cas是比synchronized效率要好的

 

4.乐观锁和悲观锁的区别

乐观锁允许别的线程修改变量,如果别的线程修改了变量那就自旋

悲观锁不允许别的线程修改变量,每次上锁的时候别的线程都会阻塞

 

5.关键字volatile

可见性:在线程中使用volatile修饰共享变量,可以防止编译器优化的发生。

下述例子中,下方的线程while(flag)被JIT(即时编译器)优化为了while(true),从而导致上面的线程修改flag下面的线程却读不到结果,这时我们可以给flag添加volatile来阻止编译器优化

static boolean flag=true;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            flag=false;
            System.out.println(flag+"已经修改");
        }).start();
        new Thread(()->{
            int i=0;
            while (flag){
                i++;
            }
            System.out.println(flag+"_"+i);
        }).start();
    }

禁止指令重排序:阻止一些读写操作越过屏障发生一些意外问题(写是防止当前指令越过上方指令,读是防止当前指令越过下方指令)

 

6.什么是AQS

AQS是抽象队列同步器,与synchronized不同的是他是由java实现的,并且锁激烈竞争的情况下有多种解决方案而不是像synchronized一样只有重量级锁

通过volatile保证state的可见性,然后当某一线程持有state后改变其数值,后续等待线程进入队列,依据队列完成排队

如何保证原子性:利用CAS在抢state时保证原子性

 

7.什么是公平锁:

新来的线程和队列中等待的线程争抢锁资源

非公平锁:

新来的线程只能进入队列的tail,只有队列的head能获取锁资源

注意,一般情况下公平锁的效率没有非公平锁高,公平锁的吞吐量较低

 

8.ReentrantLock可重入锁的原理

reentrantLock是基于AQS队列+CAS实现的,有无参构造函数和是否使用公平锁的构造函数,其中无参情况下默认是false

 

9.synchronized和lock的区别

  • 语法上:synchronized是关键字,底层由C++实现,来自jvm;lock是接口,底层java原生,来自jdk。
  • 功能上:都是悲观锁,互斥同步;lock有比synchronized更丰富的功能,lock除了正常锁以外还有公平锁,可打断锁,超时锁,多条件锁(这个类似于await和notify),并且读写锁就是是lock。但是synchronized在退出代码块后会自动释放,而lock需要手动调用unlock来释放锁。
  • 性能上:竞争不激烈的时候synchronized因为有偏向锁和轻量级锁优于lock,在竞争激烈的情况下lock具有更好的性能

 

10.死锁的产生条件

一个线程同时获取多把锁

如何检查死锁的发生:

  • 先用jps查看当前进程,进程里如果有死锁会显示xxx线程为deadlock,再用jstack查看详细信息
  • 在jdk目录中找jconsole,此时能选择你在jps里查看的所有进程

 

11.讲讲concurrentHashMap

JDK1.7使用segment数组+hashmap实现了concurrenthashmap;通过对key的hash计算找到对应的segment数组,然后通过reentrantLock锁住具体的segment数组,高并发的时候会通过CAS自旋锁来保证数据安全,然后再通过hash定位具体位置。劣势就是多个key如果hash相同的话他们就会阻塞。segment数组不能进行扩容,这也导致1.7的concurrenthashmap的性能不好

JDK1.8版本下采用CAS和synchronized对HashMap进行了增强。

利用CAS来控制扩容的实现,为头结点上锁,暂停其他线程的put操作,避免了多线程的插入冲突;在空位置新增节点时,也会采用CAS确保并发下能插入成功

synchronized只锁链表或者红黑树的首节点,保证数组节点只能被一个线程修改,降低了锁的颗粒度并且只要hash不冲突就不会有效率问题;在扩容时通过synchronized保证了数据迁移的一致性和完整性

 

12.java如何保证多线程的执行安全

原子性:一个线程在CPU中的操作是不可暂停的,是无法中断的。这里我们是通过锁解决,保证数据正确

可见性:一个线程对共享变量的修改对另一个线程可见。这里我们使用volatile保证可见性

有序性:处理器为了提高程序运行效率,对输入代码进行优化,不能保证程序中各个语句的执行顺序同代码中的顺序一致,但是能保证程序最终执行结果和代码顺序执行的结果一致。这里我们使用volatile保证有序性

标签:java,速通,synchronized,lock,问题,flag,线程,内存
From: https://www.cnblogs.com/kun1790051360/p/18470932

相关文章

  • 处理R动态链接库确实得问题
    参考文档https://askubuntu.com/questions/1409562/error-while-loading-shared-libraries-libicudata-so-66-libicudata-so-66-and-lib要使用清华镜像源来解决libicu66的问题,可以按照以下步骤更新的sources.list文件:打开sources.list文件:sudogedit/etc/apt/sources......
  • java反射机制
    什么是java反射呢,先来看Oracle官方的解释:“ReflectionenablesJavacodetodiscoverinformationaboutthefields,methodsandconstructorsofloadedclasses,andtousereflectedfields,methods,andconstructorstooperateontheirunderlyingcounterparts,......
  • QT项目打包成exe文件-非常详细(侧重于解决输出的exe文件没有原项目功能的问题)
    写在前面: 我是研二学生,用qt给老师项目做的一个辅助软件。项目要验收,所以需要打包qt项目成exe文件,但是我死活弄不出来,来回搞了两三天才弄好。特此写下第一篇博客,记录这个过程,并给同样困扰的新手朋友们提供一个方法。我是一个新手,期待大家的批评指正。打包流程: 1、获取初始......
  • [Java基础] 异常处理机制
    往期回顾[Java基础]基本数据类型[Java基础]运算符[Java基础]流程控制[Java基础]面向对象编程[Java基础]集合框架[Java基础]输入输出流[Java基础]异常处理机制[Java基础]Lambda表达式目录什么是异常处理?异常分类检查型异常非检查型异常(UncheckedExcepti......
  • java计算机毕业设计springboot+vue小区物业管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着城市化进程的加速,住宅小区的规模不断扩大,小区内的管理事务日益繁杂。传统的物业管理方式依赖人工操作,效率低下且容易出错。在信息技术飞速发......
  • java计算机毕业设计广告系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着互联网的迅猛发展,广告行业发生了翻天覆地的变化。广告形式和载体日益多样化,从传统的报纸、杂志、电视到如今无处不在的互联网广告等1。海量......
  • java基于springboot的在线教学平台(源码+vue+部署文档+前后端分离等)
    收藏关注不迷路!!......
  • Java虚拟机(JVM)(7)—— 垃圾回收(1)
    文章目录前言一、方法区的回收二、垃圾判别阶段算法1、引用计数法2、可达性分析算法GCRoots对象三、常见的引用对象1、强引用2、软引用软引用的使用方法3、弱引用4、虚引用和终结器引用四、垃圾回收算法1、垃圾回收算法的评价标准2、标记清除算法3、复制算法3、......
  • 直线与圆的最值问题(高二)
    专题:直线+圆\(\qquad\qquad\)题型:最值问题\(\qquad\qquad\)难度系数:★★★ 题目已知\(P\)为圆\(C:x^2+y^2=1\)上的动点,直线\(l_1:kx-y-3k=0\)恒过定点\(A\),\(Q\)为直线\(l_2:x-y+3=0\)上的动点,则\(|PA|+3|PQ|\)的最小值为\(\underline{\quad\quad}\).  思考痕......
  • 深度讲解Java中的面对象,通俗易懂
    目录1.封装(Encapsulation)2.继承(Inheritance)3.多态(Polymorphism)4.抽象(Abstraction)总结在Java中,“面向对象编程”(Object-OrientedProgramming,简称OOP)是核心概念之一。它通过使用类和对象来组织代码,允许程序员创建可以模拟现实世界事物的代码结构。Java中的面向对象编......