Java面试题-并发篇十六

简介: Java面试题-并发篇十六

161,Java内存模型是什么?


       Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如,先行发生关系确保了:


       线程内的代码能够按先后顺序执行,这被称为程序次序规则。


       对于同一个锁,一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前,也叫做管程锁定规则。


       前一个对volatile的写操作在后一个volatile的读操作之前,也叫volatile变量规则。


       一个线程内的任何操作必需在这个线程的start()调用之后,也叫作线程启动规则。


       一个线程的所有操作都会在线程终止之前,线程终止规则。


       一个对象的终结操作必需在这个对象构造完成之后,也叫对象终结规则。

可传递性


更多介绍可以移步并发编程网:


(深入理解java内存模型系列文章:http://ifeve.com/java-memory-model-0


162,Java中interrupted 和isInterruptedd方法的区别?


       interrupted() 和 isInterrupted()的主要区别是前者会将中断状态清除而后者不会。Java多线程的中断机制是用内部标识来实现的,调用Thread.interrupt()来中断一个线程就会设置中断标识为true。当中断线程调用静态方法Thread.interrupted()来检查中断状态时,中断状态会被清零。


       非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛出InterruptedException异常的方法都会将中断状态清零。无论如何,一个线程的中断状态都有可能被其它线程调用中断来改变。


163,Java中的同步集合与并发集合有什么区别?


       同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合,不过并发集合的可扩展性更高。在Java1.5之前程序员们只有同步集合来用且在多线程并发的时候会导致争用,阻碍了系统的扩展性。Java5介绍了并发集合像ConcurrentHashMap,不仅提供线程安全还用锁分离和内部分区等现代技术提高了可扩展性。


       不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有他们如何实现的线程安全上。


       同步HashMap, Hashtable, HashSet, Vector, ArrayList 相比他们并发的实现(ConcurrentHashMap, CopyOnWriteArrayList, CopyOnWriteHashSet)会慢得多。造成如此慢的主要原因是锁, 同步集合会把整个Map或List锁起来,而并发集合不会。并发集合实现线程安全是通过使用先进的和成熟的技术像锁剥离。


       比如ConcurrentHashMap 会把整个Map 划分成几个片段,只对相关的几个片段上锁,同时允许多线程访问其他未上锁的片段。


       同样的,CopyOnWriteArrayList 允许多个线程以非同步的方式读,当有线程写的时候它会将整个List复制一个副本给它。


       如果在读多写少这种对并发集合有利的条件下使用并发集合,这会比使用同步集合更具有可伸缩性。

164,什么是线程池? 为什么要使用它?


       创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)


       线程池的作用,就是在调用线程的时候初始化一定数量的线程,有线程过来的时候,先检测初始化的线程还有空的没有,没有就再看当前运行中的线程数是不是已经达到了最大数,如果没有,就新分配一个线程去处理。


       就像餐馆中吃饭一样,从里面叫一个服务员出来;但如果已经达到了最大数,就相当于服务员已经用尽了,那没得办法,另外的线程就只有等了,直到有新的“服务员”为止。


       线程池的优点就是可以管理线程,有一个高度中枢,这样程序才不会乱,保证系统不会因为大量的并发而因为资源不足挂掉。


165,Java中活锁和死锁有什么区别?


       活锁:一个线程通常会有会响应其他线程的活动。如果其他线程也会响应另一个线程的活动,那么就有可能发生活锁。同死锁一样,发生活锁的线程无法继续执行。然而线程并没有阻塞——他们在忙于响应对方无法恢复工作。这就相当于两个在走廊相遇的人:甲向他自己的左边靠想让乙过去,而乙向他的右边靠想让甲过去。可见他们阻塞了对方。甲向他的右边靠,而乙向他的左边靠,他们还是阻塞了对方。


       死锁:两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候,死锁会让你的程序挂起无法完成任务。


166,如何避免死锁?



死锁的发生必须满足以下四个条件:


       互斥条件:一个资源每次只能被一个进程使用。


       请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。


       不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。


       循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。


三种用于避免死锁的技术:


       加锁顺序(线程按照一定的顺序加锁)


       加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)


       死锁检测


(死锁原因及如何避免更深理解移步:http://blog.csdn.net/ls5718/article/details/51896159


167,notify()和notifyAll()有什么区别?


       1,notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。


       2,void notify(): 唤醒一个正在等待该对象的线程。


       3,void notifyAll(): 唤醒所有正在等待该对象的线程。


两者的最大区别在于:


        notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。


        notify他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁,此时如果该对象没有再次使用notify语句,即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。


168,什么是可重入锁(ReentrantLock)?


       Java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为Java 类,而不是作为语言的特性来实现。这就为Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。            ReentrantLock 类实现了Lock ,它拥有与synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM可以花更少的时候来调度线程,把更多时间用在执行线程上。)


         Reentrant 锁意味着什么呢?简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放。这模仿了synchronized 的语义;如果线程进入由线程已经拥有的监控器保护的synchronized 块,就允许线程继续进行,当线程退出第二个(或者后续)synchronized块的时候,不释放锁,只有线程退出它进入的监控器保护的第一个synchronized 块时,才释放锁。

169,读写锁可以用于什么应用场景?


       读写锁可以用于 “多读少写” 的场景,读写锁支持多个读操作并发执行,写操作只能由一个线程来操作


       ReadWriteLock对向数据结构相对不频繁地写入,但是有多个任务要经常读取这个数据结构的这类情况进行了优化。ReadWriteLock使得你可以同时有多个读取者,只要它们都不试图写入即可。如果写锁已经被其他任务持有,那么任何读取者都不能访问,直至这个写锁被释放为止。


ReadWriteLock 对程序性能的提高主要受制于如下几个因素:


1,数据被读取的频率与被修改的频率相比较的结果。


2,读取和写入的时间


3,有多少线程竞争


4,是否在多处理机器上运行


       对Java线程,并发方面的知识,这里发现了一个很不错的网站(并发编程网),这个网站对这块知识罗列有条理又很系统,有这方面需求想要深入学习的小伙伴可以看看:http://ifeve.com


Java知音公众号推送Java开发中的一些必备技能,包括但不限于数据库、Java核心、流行框架、管理工具以及服务器相关,同时为您精选流行的开源项目,必会的面试选题,练手项目,优质视频资源等。让您闲暇之余巩固一下自己的知识,不知不觉中提高自己的开发水平。

相关文章
|
3月前
|
缓存 Java 关系型数据库
2025 年最新华为 Java 面试题及答案,全方位打造面试宝典
Java面试高频考点与实践指南(150字摘要) 本文系统梳理了Java面试核心考点,包括Java基础(数据类型、面向对象特性、常用类使用)、并发编程(线程机制、锁原理、并发容器)、JVM(内存模型、GC算法、类加载机制)、Spring框架(IoC/AOP、Bean生命周期、事务管理)、数据库(MySQL引擎、事务隔离、索引优化)及分布式(CAP理论、ID生成、Redis缓存)。同时提供华为级实战代码,涵盖Spring Cloud Alibaba微服务、Sentinel限流、Seata分布式事务,以及完整的D
148 0
|
2月前
|
缓存 Java API
Java 面试实操指南与最新技术结合的实战攻略
本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
293 0
|
2月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
269 83
|
2月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
214 83
|
2月前
|
SQL 缓存 安全
深度理解 Java 内存模型:从并发基石到实践应用
本文深入解析 Java 内存模型(JMM),涵盖其在并发编程中的核心作用与实践应用。内容包括 JMM 解决的可见性、原子性和有序性问题,线程与内存的交互机制,volatile、synchronized 和 happens-before 等关键机制的使用,以及在单例模式、线程通信等场景中的实战案例。同时,还介绍了常见并发 Bug 的排查与解决方案,帮助开发者写出高效、线程安全的 Java 程序。
124 0
|
3月前
|
算法 架构师 Java
Java 开发岗及 java 架构师百度校招历年经典面试题汇总
以下是百度校招Java岗位面试题精选摘要(150字): Java开发岗重点关注集合类、并发和系统设计。HashMap线程安全可通过Collections.synchronizedMap()或ConcurrentHashMap实现,后者采用分段锁提升并发性能。负载均衡算法包括轮询、加权轮询和最少连接数,一致性哈希可均匀分布请求。Redis持久化有RDB(快照恢复快)和AOF(日志更安全)两种方式。架构师岗涉及JMM内存模型、happens-before原则和无锁数据结构(基于CAS)。
82 5
|
3月前
|
安全 Java API
2025 年 Java 校招面试常见问题及详细答案汇总
本资料涵盖Java校招常见面试题,包括Java基础、并发编程、JVM、Spring框架、分布式与微服务等核心知识点,并提供详细解析与实操代码,助力2025校招备战。
139 1
|
3月前
|
算法 Java 微服务
2025 年 Java 面试宝典社招春招秋招实操全方位攻略
2025年Java面试宝典涵盖核心技术及最新趋势,分为四大板块:1. Java基础:深入数据类型、多态等特性,结合学生信息管理等实例;2. JVM核心:解析内存模型与GC算法,附多线程转账等场景应用;3. 高并发方案:详解synchronized与线程池配置,提供Web服务器优化案例;4. Spring生态:剖析IoC/AOP原理,演示微服务架构实现。特别新增Java 17+特性实操,包括Record类、密封接口等语法糖,整合Spring Boot 3、响应式编程及云原生技术,通过订单状态机、API网关配置。
196 1
|
3月前
|
缓存 算法 NoSQL
校招 Java 面试高频常见知识点深度解析与实战案例详细分享
《2025校招Java面试核心指南》总结了Java技术栈的最新考点,涵盖基础语法、并发编程和云原生技术三大维度: 现代Java特性:重点解析Java 17密封类、Record类型及响应式Stream API,通过电商案例演示函数式数据处理 并发革命:对比传统线程池与Java 21虚拟线程,详解Reactor模式在秒杀系统中的应用及背压机制 云原生实践:提供Spring Boot容器化部署方案,分析Spring WebFlux响应式编程和Redis Cluster缓存策略。
70 0

热门文章

最新文章