1、Java内存模型是什么?

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

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

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

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

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

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

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

 

2、Java中interrupted 和isInterruptedd方法的区别?

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

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

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

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

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

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

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

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

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

4、什么是线程池? 为什么要使用它?

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

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

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

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

5、Java中活锁和死锁有什么区别?

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

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

6、如何避免死锁?

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

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

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

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

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

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

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

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

    死锁检测

  详情可查阅什么是死锁?死锁发生的四个必要条件是什么?如何避免和预防死锁产生?

7、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,而不是锁。

8、什么是可重入锁(ReentrantLock)? 

  Java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为Java 类,而不是作为语言的特性来实现。这就为Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。

  ReentrantLock 类实现了Lock ,它拥有与synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM可以花更少的时候来调度线程,把更多时间用在执行线程上。)
  Reentrant 锁意味着什么呢?简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放。这模仿了synchronized 的语义;如果线程进入由线程已经拥有的监控器保护的synchronized 块,就允许线程继续进行,当线程退出第二个(或者后续)synchronized块的时候,不释放锁,只有线程退出它进入的监控器保护的第一个synchronized 块时,才释放锁。

9、读写锁可以用于什么应用场景?
  读写锁可以用于 “多读少写” 的场景,读写锁支持多个读操作并发执行,写操作只能由一个线程来操作。
  ReadWriteLock对向数据结构相对不频繁地写入,但是有多个任务要经常读取这个数据结构的这类情况进行了优化。ReadWriteLock使得你可以同时有多个读取者,只要它们都不试图写入即可。如果写锁已经被其他任务持有,那么任何读取者都不能访问,直至这个写锁被释放为止。
ReadWriteLock 对程序性能的提高主要受制于如下几个因素:
  1,数据被读取的频率与被修改的频率相比较的结果。
  2,读取和写入的时间
  3,有多少线程竞争

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

[ Java面试题 ]并发篇的更多相关文章

  1. java面试题——高级篇

    一.集合 Hashmap的原理 源码分析参考文章:http://www.cnblogs.com/xwdreamer/archive/2012/06/03/2532832.html 题目参考文章:htt ...

  2. Java面试题-并发容器和框架

    1. 如何让一段程序并发的执行,并最终汇总结果? 答:使用CyclicBarrier 和CountDownLatch都可以,使用CyclicBarrier 在多个关口处将多个线程执行结果汇总,Coun ...

  3. 史上最难的一道Java面试题 (分析篇)

    博客园 匠心零度 转载请注明原创出处,谢谢! 无意中了解到如下题目,觉得蛮好. 题目如下: public class TestSync2 implements Runnable { int b = 1 ...

  4. [ Java面试题 ]基础篇之一

    1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...

  5. [ Java面试题 ]多线程篇

    1.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速.比如,如果一个线程完成一 ...

  6. [ Java面试题 ]泛型篇

    1.Java中的泛型是什么 ? 使用泛型的好处是什么? 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 好处: 1.类型安全,提供编译期间的类 ...

  7. [ Java面试题 ]WEB篇

    1.AJAX有哪些有点和缺点? 优点: 1.最大的一点是页面无刷新,用户的体验非常好. 2.使用异步方式与服务器通信,具有更加迅速的响应能力. 3.可以把以前一些服务器负担的工作转嫁到客户端,利用客户 ...

  8. Java面试题---基础篇

    经常阅读一些牛人的基础博以及相关个人经历,你才发现自己真的不够努力,人生路漫漫,希望本人以及看客能走出一条自己不后悔的人生路,骚年  加油!!! 回归正题 一  java基础知识点 1)java面向对 ...

  9. Java面试题-基础篇二(干货)

    11.是否可以从一个static方法内部发出对非static方法的调用? 不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用 ...

随机推荐

  1. go http

    先看一个简单的 tcp 连接: // server ln, err := net.Listen("tcp", ":8000") if err != nil {} ...

  2. python学习:元组和嵌套

    tuple(元组):只是可读,不可以修改# tup1 = () #空元组# tup2 = (20,) #元组内有一个元素,需要在元素后添加逗号 a = (1,2,3,4)print(a[1])a[1] ...

  3. linq给list集合数据分页

    var lastlist= newlist.Skip(pageindex * pagesize).Take(pagesize);

  4. Tomcat7在centos7.3上正常运行,在centos7.2就不行了

    我在jdk1.7的环境下,把一个tomcat7从一台centos7.3的服务器迁移到7.2,理论上讲  迁移完成之后只要端口没有被占用,环境变量配置完成,Tomcat是可以正常启动的(空的Tomcat ...

  5. Java 将容器List里面的内容保存到数组

    import java.util.List; import java.util.ArrayList; public class listToArr { public static void main( ...

  6. The SQL Server instance returned an invalid or unsupported protocol version during login negotiatio

    在使用.net core 连接sqlserver的时候遇到了这个问题 从字面意思理解大致是个什么版本不支持, 谷歌一下吧,ok,看到这个2000我就知道什么问题了 我的数据库还是2000的,总算把20 ...

  7. 请问浏览器访问www.baidu.com经历了怎样的过程?

    1.查找浏览器缓存 首先会查找浏览器缓存,浏览器会保存一段时间你之前访问过的网址的DNS信息,不同的浏览器保存的时长不等. 2.查找系统缓存 如果上面的步骤没有找到对应的DNS信息,这个时候浏览器会尝 ...

  8. 排查MongoDB CPU使用率高的问题

    1.公司业务调整,把一部分数据由Redis转至MongoDB,业务在测试环境正常,生产环境上线后发现压力一上来MongoDB的服务直接把CPU占满了,和开发的同学分析了一下也参考了一下百度上类似的问题 ...

  9. ChartControl设置坐标轴范围

    需求:有一条坐标轴是用来表示百分比的,所以刻度范围只能是从0 - 100: 解决方法:运行chatcontrol设计器,选中需要设置的轴,如下图: 设置Whole range 的最大最小值: 默认情况 ...

  10. 关于Http协议,你必须要知道的

    转自:https://segmentfault.com/a/1190000016751071 引言 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用 ...