Java面经之Java并发

  1. 进程:程序的一次执行 线程:一个进程在执行的过程可以产生多个线程 多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈、本地方法栈   其中程序计数器是为了线程切换后恢复到正确的执行位置;虚拟机栈和本地方法栈是为了保证线程中的局部变量不被别的线程访问到
  2. 一个 Java 程序的运行是 main 线程和多个其他线程同时运行
  3. 创建线程  Java创建线程有很多种方式啊,像实现Runnable、Callable接口、继承Thread类、创建线程池等等,不过这些方式并没有真正创建出线程,严格来说,Java就只有一种方式可以创建线程,那就是通过new Thread().start()创建。
    而所谓的Runnable、Callable……对象,这仅仅只是线程体,也就是提供给meme务,并不属于真正的Java线程,它们的执行,最终还是需要依赖于new Thread()……
  4. 线程的生命周期 ready-running-wait-timed_waiting-blocked-terminated
  5. 线程上下文切换 
  6. thread.sleep()和object.wait()方法区别 一个是thread类的静态方法一个是object的本地方法 sleep没有释放锁,是让当前线程暂停执行,不实际到对象类,也不需要获得对象锁          wait释放了锁 ,自动释放当前线程占有的对象所   被调用后不会自动苏醒,需要noitfy()方法唤醒
  7. yield()让当前正在运行的线程回到可运行状态,以允许具有相同或者更高优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同或者更高优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。
  8. 调用 start() 方法方可启动线程并使线程进入就绪状态,直接执行 run() 方法的话不会以多线程的方式执行
  9. 并发:多个作业在同一时间段执行   并行 :多个作业在同一时刻执行
  10. JVM 本身不负责线程的调度,而是将线程的调度委托给操作系统。操作系统通常会基于线程优先级和时间片来调度线程的执行,高优先级的线程通常获得 CPU 时间片的机会更多
  11. 单核 CPU 同时运行多个线程的效率是否会高,取决于线程的类型和任务的性质。对于单核 CPU 来说,如果任务是 CPU 密集型的,那么开很多线程会影响效率;如果任务是 IO 密集型的,那么开很多线程会提高效率。
  12. 线程安全:指的是在多线程环境下,对于同一份数据,不管有多少个线程同时访问,都能保证这份数据的正确性和一致性。
  13. 线程死锁:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。检测可以通过JDK 的jconcole工具进行检测
  14. volatile保证数据的可见性,指示JVM这个变量是共享且不稳定的,每次使用它都需要到主存中进行读取    同时,防止 JVM 的指令重排序。但是不保证原子性,因为它没有加锁
  15. 悲观锁:共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。乐观锁:通常多用于写比较少的情况(多读场景,竞争较少),这样可以避免频繁加锁影响性能。不过,乐观锁主要针对的对象是单个共享变量  
  16. 如何实现乐观锁:版本号控制  CAS
  17. CAS:一个预期值和要更新的变量值进行比较,两值相等才会进行更新
  18. CAS问题:ABA问题,循环时间开销大
  19. synchronized 主要解决的是多个线程之间访问资源的同步性,可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。 可以修饰实例方法(需要获取当前对象实例的锁)、静态方法(需要获得当前类的锁)和代码块
  20. synchronized 同步语句块的实现使用的是 monitorentermonitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。

    synchronized 修饰的方法并没有 monitorenter 指令和 monitorexit 指令,取得代之的确实是 ACC_SYNCHRONIZED 标识,该标识指明了该方法是一个同步方法。

  21. synchronized 关键字和 volatile 关键字是两个互补的存在   volatile 关键字只能用于变量而 synchronized 关键字可以修饰方法以及代码块 。volatile 关键字能保证数据的可见性,但不能保证数据的原子性。synchronized 关键字两者都能保证。volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized 关键字解决的是多个线程之间访问资源的同步性

  22. ReentrantLock ReentrantReadWriteLock  StampedLock 

  23. ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。这个变量的每个线程都会有这个变量的本地副本,这也是ThreadLocal变量名的由来。他们可以使用 get()set() 方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题。

  24. 每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreadLocal为 key ,Object 对象为 value 的键值对。ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。使用完 ThreadLocal方法后最好手动调用remove()方法
  25. 线程池:降低资源消耗、提高响应速度、提高管理性
  26. ThreadPoolExecutor 构造函数
  27. 线程池的核心线程数不会被回收,这样才会被回收
  28. 线程池的回收策略  ThreadPoolExecutor.AbortPolicy(默认,抛出异常拒绝新任务的处理)ThreadPoolExecutor.CallerRunsPolicy  CallerRunsPolicy 和其他的几个策略不同,它既不会抛弃任务,也不会抛出异常,而是将任务回退给调用者,使用调用者的线程来执行任务。这样可能会导致线程池阻塞,进而导致后续任务无法及时执行,严重情况下会OOM  任务持久化 ,Netty它的拒绝策略则是直接创建一个线程池以外的线程处理这些任务
  29. 简单来说:使用execute()时,该异常会导致当前线程终止,并且异常会被打印到控制台或日志文件中。未捕获异常导致线程终止,线程池创建新线程替代;使用submit()时,异常被封装在Future中,线程继续复用
  30. 命名
    ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").setDaemon(true).build();
    ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
    

    大小:多线程会增加上下文切换成本,任务从保存到再加载就是一次上下文切换

  31. 如何设计一个根据任务优先级来执行的线程池  可以考虑使用 PriorityBlockingQueue  提交到线程池的任务实现 Comparable 接口,并重写 compareTo 方法来指定任务之间的优先级比较规则。创建 PriorityBlockingQueue 时传入一个 Comparator 对象来指定任务之间的排序规则(推荐)。

  32. 为了提升执行速度/性能,计算机在执行程序代码的时候,会对指令进行重排序。 简单来说就是系统在执行代码的时候并不一定是按照你写的代码的顺序依次执行。指令重排序可以保证串行语义一致,但是没有义务保证多线程间的语义也一致 ,所以在多线程下,指令重排序可能会导致一些问题

  33. JMM  Java内存模型   因为并发编程下,像 CPU 多级缓存和指令重排这类设计可能会导致程序运行出现一些问题 JMM 说白了就是定义了一些规范来解决这些问题,开发者可以利用这些规范更方便地开发多线程程序。

  34. 并发编程的三个重要特征:原子性、可见性、有序性

  35. 几个常用的内置线程池的作用  FixedThreadPool和SingleThreadExecutor 任务队列容量为Integer.MAX_VALUE;CachedThreadPoolCachedThreadPool 使用的是同步队列 SynchronousQueue, 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程  所以都不推荐使用,线程池必须手动通过 ThreadPoolExecutor 的构造函数来声明,避免使用Executors 类创建线程池,会有 OOM 风险。说白了就是:使用有界队列,控制线程创建数量。

  36. 用完线程池要记得关闭 其中shutdown() :关闭线程池,线程池的状态变为 SHUTDOWN。线程池不再接受新任务了,但是队列里的任务得执行完毕  它只是异步的通知线程池进行关闭处理awaitTermination要同步等待线程池彻底关闭后才继续往下执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3267702.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Zabbix自定义监控内容部署+邮件报警+Zabbix自愈+Zabbix批量添加主机

一、自定义监控项 1.1自定义监控项原理 1)先明确获取监控指标数据的命令或脚本; 2)在被监控主机配置文件子目录(/etc/zabbix/zabbix_agent2.d/)中创建以.conf后缀的监控项配置文件,自定义获取监控指标数据的键值; …

【VUE】个人记录:父子页面数据传递

1. 父传子 在父页面中&#xff0c;调用子页面的组件位置处&#xff0c;通过“&#xff1a;”进行参数传递 <child-component :childData"parentData"></child-component>parentData对象&#xff0c;需要在父页面的data中进行初始化声明 在子页面中&am…

算法与算法分析

目录 一.前言 二.算法的特性和要求 三.分析算法--时间效率 四. 分析算法--空间效率 一.前言 算法就是对特定问题求解方法和步骤的一种描述&#xff0c;它是指令的有限序列。其中&#xff0c;每个指令表示一个或多个操作。总而言之&#xff0c;我们数据结构就是通过算法实现操…

全球CG盛事:世界3D渲染大赛震撼开幕!

在数字艺术的浪潮中&#xff0c;CG&#xff08;计算机图形学&#xff09;已经成为现代视觉艺术不可或缺的一部分。它不仅推动了电影、游戏和动画产业的发展&#xff0c;更激发了无数艺术家的创造力。今天&#xff0c;我们迎来了一个全球CG界的盛事——世界3D渲染大赛的震撼开幕…

【Unity2D 2022:UI】TextMeshPro组件无法显示中文

在Unity中创建了一个预制体Card&#xff0c;上面挂载了一些Text Mesh Pro组件用来显示卡牌信息。但是在输入文字后&#xff0c;发现无法显示中文&#xff1a; 解决方法如下&#xff1a; 一、导入字体文件&#xff08;ttf格式&#xff09;和常用字字集&#xff08;txt格式&…

【LLM大模型】LLaMA3微调部署真不难!拿走这份教程,轻松掌握LLaMA大模型微调!

今天给大家分享一个爆火的llama3教程&#xff0c;也就是下面这份&#xff1a; 这个项目是基于Meta最新发布的新一代开源大模型Llama-3开发的&#xff0c;是Chinese-LLaMA-Alpaca开源大模型相关系列项目的第三期。本项目开源了中文Llama-3基座模型和中文Llama-3-Instruct指令精…

使用curl测试websocket服务是否能正常连入

部分场景&#xff0c;前端连接不上websocket服务&#xff0c;需要从后台验证websocket服务是否能连入&#xff0c;判断防火墙是否开通&#xff0c;反向代理是否配置正确&#xff0c;可以使用curl测试服务器websocket服务是否正常。 分行命令 curl --include \--no-buffer \--…

自监督学习概述(Self-Supervised Learning,SSL)

自监督学习&#xff08;Self-Supervised Learning&#xff0c;SSL&#xff09;是一种机器学习方法&#xff0c;旨在利用未标记数据进行训练。这种方法通过从数据本身生成伪标签&#xff0c;来创建监督信号&#xff0c;使得模型能够学习有效的数据表示。自监督学习在深度学习领域…

Vue的安装配置

1.安装node js Node.js — 在任何地方运行 JavaScript (nodejs.org) 2.测试nodejs是否安装成功 node -v npm -v3.通过npm 安装 vue npm install -g vue/cli4.测试vue是否安装成功 vue --version5.打开PyCharm&#xff0c;创建项目&#xff1a;flask-web vue create flask…

论文快过(图像配准|Coarse_LoFTR_TRT)|适用于移动端的LoFTR算法的改进分析 1060显卡上45fps

项目地址&#xff1a;https://github.com/Kolkir/Coarse_LoFTR_TRT 创建时间&#xff1a;2022年 相关训练数据&#xff1a;BlendedMVS LoFTR [19]是一种有效的深度学习方法&#xff0c;可以在图像对上寻找合适的局部特征匹配。本文报道了该方法在低计算性能和有限内存条件下的…

【已解决】TypeError: argument of type ‘int’ is not iterable

【已解决】TypeError: argument of type ‘int’ is not iterable 在Python编程中&#xff0c;TypeError: argument of type int is not iterable是一个常见的错误。此错误表明你尝试对一个整数&#xff08;int&#xff09;执行迭代操作&#xff0c;但整数是不可迭代的。本文将…

微信小程序模拟扫码进入调试

1 2 参数就是namekeyaaa&#xff0c;上面的%3D是经过encodeURIComponent编码&#xff0c;必须使用%3D&#xff0c;不然等号会当作新的key。

【单片机毕业设计选题24081】-路灯无线数据采集器

系统功能: 手机开启2.4G WiFi热点后再给系统上电 系统操作说明&#xff1a; 上电后OLED显示 “欢迎使用智能路灯系统请稍后”&#xff0c;两秒后显示Connecting...表示 正在连接阿里云&#xff0c;正常连接阿里云后显示第一页面&#xff0c;如长时间显示Connecting...请 检…

Redis的操作以及SpringCache框架

目录 一.什么是Redis&#xff1f; 二.Redis的相关知识&#xff1a; 三.如何操作Redis&#xff1f; 1&#xff0c;常用命令&#xff1a; 2.Spring Data Redis &#xff08;1&#xff09; pom.xml 配置&#xff1a; &#xff08;2&#xff09;配置Redis数据源&#xff1a; …

转置卷积 transposed convolution

1. 转置卷积 转置卷积&#xff08;Transposed Convolution&#xff09;也叫Fractionally-strided Convolution和Deconvolution&#xff0c;但用的最多的是Transposed Convolution。 注意&#xff1a; 转置卷积不是卷积的逆运算&#xff0c;只会大小恢复为原本大小。转置卷积…

SPSS个人版是什么软件

SPSS是一款数据统计、分析软件&#xff0c;它由IBM公司出品&#xff0c;这款软件平台提供了文本分析、大量的机器学习算法、数据分析模型、高级统计分析功能等&#xff0c;软件易学且功能非常强大&#xff0c;可以使用SPSS制作图表&#xff0c;例如柱状、饼状、折线等图表&…

APP逆向 day21大姨妈逆向

一.前言 今天来和大家说一款app名叫DYM&#xff0c;我们选择版本v8.6.0&#xff0c;今天通过这个可以学到的知识点有绕过root检测&#xff0c;通过frida-rpc和自己编写一款小的app来调用so文件&#xff0c;然后再来破解登录接口 二.绕过root检测 我们进入app后发现&#xff…

C++从入门到起飞之——初始化列表类型转换static成员 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、初始化列表 2、 类型转换 3. static成员 4、完结散花 1、初始化列表 • 之前我们实现构造函数…

Qwen2模型Text2SQL微调​以及GGUF量化

Qwen2-1.5B微调 准备python环境 conda create --name llama_factory python=3.11 conda activate llama_factory部署llama-factory git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip3 install -e ".[torch,metrics]" # 如…

算法日记day 20(二叉搜索树)

一、验证二叉搜索树 题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也…