Java面试题-并发篇十六

原创 2018年01月04日 09:58:01

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核心、流行框架、管理工具以及服务器相关,同时为您精选流行的开源项目,必会的面试选题,练手项目,优质视频资源等。让您闲暇之余巩固一下自己的知识,不知不觉中提高自己的开发水平。


版权声明:所有文章出自Java知音微信公众号!

Java语言程序设计基础篇原书第十版第六章编程练习题答案

第六章 方法的部分代码,会尽快补全
  • Tanganling
  • Tanganling
  • 2016年11月27日 20:25
  • 3587

java语言程序设计基础篇第六章编程练习题

1 import java.util.Scanner; public class Main{ public static void main(String[] args){ final int...
  • gyhguoge01234
  • gyhguoge01234
  • 2016年07月05日 22:26
  • 3886

Java面试题大全(数据库部分三)

11、Oracle数据常用的备份与恢复? Oracle的备份与恢复有三种标准的模式,大致分为两大类,备份恢复(物理上的)以及导入导出(逻辑上的),而备份恢复又可以根据数据库的工作模式分为非归档模式(N...
  • huangxingchen123
  • huangxingchen123
  • 2016年09月29日 09:22
  • 2363

黑马程序员java学习日记十六 7k面试题交通灯管理系统讲解

I一、需求分析 1,模拟实现十字路口的交通灯管理系统逻辑,异步随机生成按照各个路线行驶的车辆。 例如:        由南向而来去往北向的车辆 ---- 直行车辆        由西向而来...
  • u011532797
  • u011532797
  • 2013年08月21日 14:00
  • 529

黑马程序员--十六、7K月薪面试题--银行业务系统

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ---------------------- 黑马程序员-张孝祥老师银行业务...
  • u012449350
  • u012449350
  • 2014年01月13日 21:22
  • 312

java并发多线程面试题和答案

1.java中有几种方法可以实现一个线程? 两种,一种是实现Runnable接口,另一种是继承Thread 2.如何停止一个正在运行的线程?   this.stop()方法结束线...
  • u010741376
  • u010741376
  • 2015年06月09日 15:21
  • 620

Java多线程并发基础面试题回答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Jav...
  • youyou_yo
  • youyou_yo
  • 2017年06月14日 16:34
  • 211

Java面试题--多线程、并发及线程的基础问题

1)Java 中能创建 Volatile 数组吗? 能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。我的意思是,如果改变引用指向的数组,将会受到 v...
  • oChangWen
  • oChangWen
  • 2016年05月12日 15:19
  • 1222

java面试题15--迭代器并发修改异常ConcurrentModificationException

问题: 我有一个集合,如下,请问,我想判断里面有没有”world”这个元素,如果有,我就添加一个”javaee”元素,请写代码实现。 使用普通迭代器出现的异常: Concur...
  • u014726937
  • u014726937
  • 2016年08月25日 11:54
  • 1089

Java并发多线程面试题 Top 50

本文由 ImportNew - 李 广 翻译自 javarevisited。欢迎加入翻译小组。转载请见文末要求。 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要...
  • i10630226
  • i10630226
  • 2015年12月18日 10:48
  • 1598
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java面试题-并发篇十六
举报原因:
原因补充:

(最多只允许输入30个字)