Java并发编程面试题

这篇具有很好参考价值的文章主要介绍了Java并发编程面试题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、线程、进程、程序

二、线程状态

 三、线程的七大参数

四、线程有什么优缺点?

五、start 和 run 方法有什么区别?

六、wait 和 sleep的区别?

七、lock与synchronized的区别

八、Volatile关键字是线程安全的吗?底层原理是什么?

九、synchronized作用和底层原理?

十一、ThreadLocal是线程安全的吗?底层原理是什么?会存在内存泄露吗?

十二、HashMap和ConcurrentHashMap有什么区别?

十三、HashMap和HashTable有什么区别?

一、线程、进程、程序

进程: 我们把运行中的程序叫做进程,每个进程都会占用内存与CPU资源,进程与进程之间互相独立.

线程: 线程就是进程中的一个执行单元,负责当前进程中程序的执行。一个进程可以包含多个线程。多线程可以提高程序的并行运行效率。

程序:是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。

二、线程状态

1.新建(New):创建线程对象时

2.就绪(Runnable):线程调用start方法,有执行资格没有执行权

3.运行:当就绪状态时抢到cpu的执行权之后,进入运行状态

4.阻塞(Blocked):当获取锁失败后,进入阻塞状态

5.等待(Waiting):等待被notify()方法唤醒

6.休眠(sleep):休眠一段时间,时间到了之后,进入就绪状态。

7.终止(Terminated):线程死亡

Java并发编程面试题,java,开发语言,jvm

 三、线程的七大参数

1.核心线程数(corePoolSize):表示保持活动状态的最小线程数。

2.最大线程数(maximumPoolSize):表示允许创建的最大线程数。

3.空闲时间(keepAliveTime):表示当线程数量超过核心线程数时,多余的空闲线程能够保持存活的时间。

4.阻塞队列(workQueue):表示用于存储等待执行的任务的阻塞队列。

5.单位(unit):表示空闲时间的单位,例如毫秒、秒等。

6.拒绝策略(rejectedExecutionHandler):表示当任务无法提交给线程池执行时采取的策略。

当线程任务进来时,首先尝试创建核心线程进行执行。如果线程池中的线程数量已经达到了核心线程数,

并且阻塞队列也已经满了,那么就会尝试创建新的线程进行执行。

如果线程池中的线程数量已经达到了最大线程数,并且阻塞队列也已经满了,那么就会执行拒绝策略。

示例:假设线程池的核心线程数为 10,最大线程数为 20,阻塞队列容量为 50,

则当有 100 个任务进入线程池时,会有 10 个核心线程立刻执行任务,50 个任务进入阻塞队列,

再有 10 个线程被创建并立即执行剩余的任务。最后还剩下 30 个任务无法执行,就会被拒绝执行。

Java并发编程面试题,java,开发语言,jvm

四、线程有什么优缺点?

优点:

1. 在多核CPU中,通过并行计算提高程序性能. 比如一个方法的执行比较耗时,现在把这个方法逻辑拆分,分为若干个线程并发执行,提高程序效率。

2. 可以解决网络等待、io响应导致的耗时问题

3. 提高CPU的使用率.提高网络资源的利用率

缺点:

1. 线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;

2. 线程之间对共享资源的访问会造成资源安全问题;

3. 多线程存在上下文切换问题CPU 通过时间片分配算法来循环执行任务,所以本身就会占用cpu资源

五、start 和 run 方法有什么区别?

        调用start方法方可启动线程,而run方法只是thread类中的一个普通方法调用,还是在主线程里执行。

六、wait 和 sleep的区别?

相同点:wait(long) 和 sleep(long) 的效果都是让当前线程暂时放弃 CPU 的使用权,进入阻塞状态

不同点:

sleep是Thread的静态方法,而 wait()都是 Object 的成员方法,每个对象都有。

sleep方法是暂停当前线程,相当于休眠一段时间,之后会自动唤醒,而wait()必须被notify 或者notifyall方法唤醒,不然会一直阻塞。

wait方法的调用必须先获取wait对象的锁,而sleep则无此限制wait方法执行后会释放对象锁

 允许其它线程获得该对象锁(我放弃 cpu,但你们还可以用);如果在 synchronized代码块中执行,并不会释放对象锁(我放弃 cpu,你们也用不了)。

七、lock与synchronized的区别

语法层面:

1.synchronized是关键字,源码在jvm中,用c++ 语言实现

2..Lock 是接口,源码由jdk 提供,用java语言实现

3.使用 synchronized 时,退出同步代码块锁会由jvm自动释放,而使用Lock时,需要手动调用unlock方法释放锁,否则可能会导致死锁等问题。

功能层面

1. Lock 提供了更多的锁机制选择,例如公平锁、非公平锁、可重入锁、读写锁等多种类型;而 synchronized 只有一种类型,即独占锁(排他锁)。

2. Lock 应该优先考虑在高并发场景下使用,可以获得更好的性能和灵活性;而 synchronized 关键字则更适合用于简单的线程同步场景,易于使用和维护。

八、Volatile关键字是线程安全的吗?底层原理是什么?

什么是重排序?

        当一个变量被修改后,如果该变量的值没有被写入到主内存中,其他线程可能会读取到该变量的旧值,导致程序出错。

并发编程中有3大重要特性:

原子性

一个操作或者多个操作,要么全部执行成功,要么全部执行失败。满足原子性的操作,中途不可被

中断。

可见性

多个线程共同访问共享变量时,某个线程修改了此变量,其他线程能立即看到修改后的值。

有序性

        程序执行的顺序按照代码的先后顺序执行。(由于JMM模型中允许编译器和处理器为了效率,进行指令重排序的优化。指令重排序在单线程内表现为串行语义,在多线程中会表现为无序。那么多线程并发编程中,就要考虑如何在多线程环境下可以允许部分指令重排,又要保证有序性)

那么volatile关键字是如何保证可见性和有序性呢?

保证可见性:当一个变量被volatile修饰后,JVM会把工作内存中的最新变量值强制刷新到主内存中,会导致其他线程中的缓存失效。这样,其他线程使用缓存时,发现本地工作内存中此变量失效,便会从主内存中获取,这样获取到的值就是最新的值,实现了线程可见性

Java并发编程面试题,java,开发语言,jvm

线程

线程是程序执行的最小单位,多个线程可以同时执行。在Java中,每个线程都有自己的工作内存

工作内存

        每个线程都有自己的工作内存,也称为线程的本地内存。工作内存是线程私有的,用于存储线程执行过程中的栈帧、局部变量等信息

主内存

        主内存是所有线程共享的内存区域。主内存中存储着所有的变量,包括静态变量、实例变量等。主内存是线程间进行数据交互的存储区域。

保证有序性:通过编译器在生成字节码时,在指令序列中添加“内存屏障”来禁止指令重排序的,从而保证了有序性。(屏蔽在多线程环境下CPU的指令重排)

总之,Volatile关键字可以保证可见性和有序性,但不保证原子性,因此volatile不是线程安全的。

九、synchronized作用和底层原理?

1.Java关键字synchronized是用于实现多线程同步的机制,确保多个线程在访问共享资源时不会产生竞争和冲突,从而避免数据不一致的情况。其主要原理是基于Java对象的内部锁,即监视器锁(Monitor Lock),确保在同一时刻只有一个线程可以访问被保护的代码块或方法

2.当一个线程尝试获取被synchronized关键字保护的资源时,如果该资源已被其他线程占用,该线程就会进入阻塞等待状态。当占用资源的线程释放该资源时,等待队列中的线程会竞争获取该资源,并且只有一个线程会成功获取到该资源,其他线程继续等待。

3.synchronized关键字保证了可见性和原子性,可见性是通过JVM底层的内存屏障来实现的,原子性则是通过监视器锁的互斥性来实现的。

在synchronized块内,线程获得了锁,它将会清空工作内存,从而使得该线程使用的变量能够从主内存中重新读取,同时也会把工作内存中的变量写回到主内存中。这样,其他线程就可以读取到最新的值,从而保证了可见性。

十一、ThreadLocal是线程安全的吗?底层原理是什么?会存在内存泄露吗?

弱引用:只要垃圾回收机制一运行,不管 JVM 内存空间是否充足,都会回收该对象占用的内存。

ThreadLocal:为共享变量在每个线程中创建一个副本,每个线程都可以访问自己内部的副本变量。通过 threadlocal 保证线程的安全性

在 ThreadLocal 类中有一个静态内部类 ThreadLocalMap(其类似于 Map),用键值对的形式存储每一个线程的变量副本,ThreadLocalMap 中元素的 key 为当前ThreadLocal 对象,而 value 对应线程的变量副本。ThreadLocal 本身并不存储值,它只是作为一个 key 保存到 ThreadLocalMap中,但是这里要注意的是它作为一个 key 用的是弱引用,因为没有强引用链,弱引用在 GC的时候可能会被回收。这样就会在 ThreadLocalMap 中存在一些key为null的键值对(Entry)。因为 key 变成 null 了,我们是没法访问这些 Entry 的,但是这些 Entry 本身是不会被清除的。如果没有手动删除对应 key 就会导致这块内存即不会回收也无法访问,也就是内存泄漏。使用完 ThreadLocal之后,记得调用 remove方法。

1.每个Thread维护一个ThreadLocalMap,这个ThreadLocalMap的key是ThreadLocal实例本身,value才是真正要存储的值Object

2.每个Thread线程内部都有一个ThreadLocalMap,Map里面存储ThreadLocal对象(key)和线程的变量副本(value)

3.Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值

4.对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。

注意:在不使用线程池的前提下,即使不调用 remove 方法,因此是ThreadLocal是弱引用,线程的"变量副本"也会被gc回收,即不会造成内存泄漏的情况。

十二、HashMap和ConcurrentHashMap有什么区别?

首先HashMap和ConcurrentHashMap都是Map接口的实现类。可以从以下三个方面分析它们的区别:

线程安全方面:由于HashMap没有加锁机制,线程不安全;ConcurrentHashMap内部加了分段锁线程安全

并发性能:由于ConcurrentHashMap采用了分段锁机制,因此可以支持多个线程同时进行读写操作,并且在高并发的场景下性能更好。而HashMap默认没有加锁,需要手动加锁,如果多个线程同时修改同一个HashMap对象,可以会出现锁竞争条件和死锁问题。

底层数据结构不同:HashMap底层使用数组+链表+红黑树,而ConcurrentHashMap底层使用分段锁(segment)机制实现。

ConcurrentHashMap底层分段锁原理

JDK1.7的时候:ConcurrentHashMap为保证线程安全,使用的是分段锁机制--->首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当线程占用锁访问的数据时,其他段数据也能访问。但是,这种方式在高并发场景下仍然存在性能瓶颈,因为多个线程仍然需要竞争同一个锁

JDK1.8之后:为提高效率,放弃了分段锁的设计,取代的是Node+CAS+Synchronized保证并发安全实现,ConcurrentHashMap将底层数据结构分成了多个小的桶(Segment),每个桶都维护了一个独立的哈希表,不同的线程可以同时访问不同的桶,从而避免了多个线程竞争同一个锁的情况,提高了并发性能和效率。syschronized只锁当前链表或红黑树的首节点,只要hash不冲突,效率就提高了。

十三、HashMap和HashTable有什么区别?

1、线程安全性

        HashTable是线程安全的,HashMap是非线程安全的。因为ashTable的核心方法都加了synchronized同步锁,hashMap没有加锁。

2、null值的处理:

        HashMap允许键和值为空(null),它可以存储null值以及使用null作为键值对。而HashTable不允许键或值为空(null),如果尝试存储Null值或使用null作为键,则会抛出NullPointerException异常。

3、遍历方式:

        HashMap可以双向遍历,并可以进行删除操作;而HashTable只能单向遍历集合元素,不能进行删除操作。

4、初始容量和扩容机制:

Hashtable默认的初始容量是11,每次扩容时容量变为原来的两倍加一

HashMap默认的初始容量是16,每次扩容时容量变为原来的两倍文章来源地址https://www.toymoban.com/news/detail-525015.html

到了这里,关于Java并发编程面试题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java并发编程面试题——线程池

    参考文章: 《Java 并发编程的艺术》 7000 字 + 24 张图带你彻底弄懂线程池 (1) 线程池 (ThreadPool) 是一种用于 管理和复用线程的机制 ,它是在程序启动时就预先创建一定数量的线程,将这些线程放入一个池中,并对它们进行有效的管理和复用,从而在需要执行任务时,可以从

    2024年02月07日
    浏览(38)
  • Java面试_并发编程_线程基础

    进程是正在运行程序的实例, 进程中包含了线程, 每个线程执行不同的任务 不同的进程使用不同的内存空间, 在当前进程下的所有线程可以共享内存空间 线程更轻量, 线程上下文切换成本一般上要比进程上下文切换低(上下文切换指的是从一个线程切换到另一个线程) 并发是单个

    2024年02月07日
    浏览(44)
  • 2023Java高频必背并发编程面试题02

    CAS 算法是 基于值来做⽐较的 ,如果当前有两个线程,⼀个线程将变量值从 A 改为 B ,再由 B 改回为 A,当前线程开始执⾏ CAS 算法时,就很容易认为值没有变化,误认为读取数据到执⾏ CAS 算法的期间,没有线程修改过数据。 juc 包提供了⼀个 AtomicStampedReference,即 在原始的

    2023年04月09日
    浏览(41)
  • 每日三道面试题之 Java并发编程 (一)

    并发编程是一种允许多个操作同时进行的编程技术,这种技术在现代软件开发中非常重要,原因如下: 充分利用多核处理器 :现代计算机通常都拥有多核处理器,通过并发编程,可以让每个核心独立执行不同的任务,从而显著提高程序的执行效率和吞吐量。 提高资源利用率

    2024年04月09日
    浏览(38)
  • 互联网Java工程师面试题·Java 并发编程篇·第五弹

    目录 52、什么是线程池? 为什么要使用它? 53、怎么检测一个线程是否拥有锁? 54、你如何在 Java 中获取线程堆栈? 55、JVM 中哪个参数是用来控制线程的栈堆栈小的? 56、Thread 类中的 yield 方法有什么作用? 57、Java 中 ConcurrentHashMap 的并发度是什么? 58、Java 中 Semaphore 是什么

    2024年02月07日
    浏览(56)
  • 【java】开发——《并发编程》

    目录 一.jmm 二.并发了什么 1.只有一个核(单核)并发还有没有意义 2.单核,还有什么可见性问题 3.并发和并行 三.volitaile 1.变量的可见性问题 2.原因是什么 3.本次修改的变量直接刷到主内存 4.声明其他内存对于这个地址的缓存无效 四.happens-befo 1.顺序性问题 五.volitaile+cas 1.原

    2024年02月22日
    浏览(37)
  • Java后端开发面试题——JVM虚拟机篇

    目录 什么是程序计数器? 你能给我详细的介绍Java堆吗? 什么是虚拟机栈 1. 垃圾回收是否涉及栈内存? 2. 栈内存分配越大越好吗? 3. 方法内的局部变量是否线程安全? 4.什么情况下会导致栈内存溢出? 5.堆栈的区别是什么? 能不能解释一下方法区(元空间)? 常量池 运行

    2024年02月09日
    浏览(30)
  • JAVA后端开发面试基础知识(一)——JVM

    Class loader(类装载) 根据给定的全限定名类名(如: java.lang.Object)来装载class文件到 Runtime data area中的method area。 Execution engine(执行引擎) 执行classes中的指令。 Native Interface(本地接口) 与native libraries交互,是其它编程语言交互的接口。 Runtime data area(运行时数据区域) 这就是我们常说

    2024年03月10日
    浏览(47)
  • 🔥🔥Java开发者的Python快速进修指南:网络编程及并发编程

    今天我们将对网络编程和多线程技术进行讲解,这两者的原理大家都已经了解了,因此我们主要关注的是它们的写法区别。虽然这些区别并不是非常明显,但我们之所以将网络编程和多线程一起讲解,是因为在学习Java的socket知识时,我们通常会将它们结合使用,以实现服务器

    2024年02月05日
    浏览(49)
  • Go 语言面试题(三):并发编程

    对于无缓冲的 channel,发送方将阻塞该信道,直到接收方从该信道接收到数据为止,而接收方也将阻塞该信道,直到发送方将数据发送到该信道中为止。 对于有缓存的 channel,发送方在没有空插槽(缓冲区使用完)的情况下阻塞,而接收方在信道为空的情况下阻塞。 例如: 协

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包