1、synchronized 的实现原理以及锁优化?

在JDK 5之前Java语言是靠synchronized关键字保证同步的。使用synchronized 关键字定义同步方法,或者在方法中使用synchronized关键字定义同步块。
但是这会导致有锁,锁机制存在以下问题:
(1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。
(2)一个线程持有锁会导致其它所有需要此锁的线程挂起。
(3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。

优化:
<1> volatile是不错的机制,但是volatile不能保证原子性。因此对于同步最终还是要回到锁机制上来。 (第25点)
<2> CAS(第6点)

2、volatile 的实现原理?

3、Java 的信号灯?

4、synchronized 在静态方法和普通方法的区别?

5、怎么实现所有线程在等待某个事件的发生才会去执行?

6、CAS?CAS 有什么缺陷,如何解决?

CAS
JDK1.4是2002年2月发布的,当时的硬件设备远没有如今这么先进,多CPU和多核还没有普及,所以在JDK1.5之前的synchronized是使用挂起线程、等待调度的方式来实现线程同步,开销较大;
而随着硬件的不断升级,在2004年9月发布的JDK5中引入了CAS机制——比较并交换——来彻底解决此问题,在一般情况下不再需要挂起(参考后文对锁级别的描述,只有进入重量级锁的时候才会使用挂起),而是多次尝试,其利用底层CPU命令实现的乐观锁机制。
从内存领域来说这是乐观锁,因为它在对共享变量更新之前会先比较当前值是否与更新前的值一致,如果是,则更新,如果不是,则无限循环执行(称为自旋),直到当前值与更新前的值一致为止,才执行更新。

CAS策略有如下需要注意的事项:
  1、在线程抢占资源特别频繁的时候(相对于CPU执行效率而言),会造成长时间的自旋,耗费CPU性能。
  2、有ABA问题(即在更新前的值是A,但在操作过程中被其他线程更新为B,又更新为A),这时当前线程认为是可以执行的,其实是发生了不一致现象,如果这种不一致对程序有影响(真正有这种影响的场景很少,除非是在变量操作过程中以此变量为标识位做一些其他的事,比如初始化配置),则需要使用AtomicStampedReference(除了对更新前的原值进行比较,也需要用更新前的stamp标志位来进行比较)。
  3、只能对一个变量进行原子性操作。如果需要把多个变量作为一个整体来做原子性操作,则应该使用AtomicReference来把这些变量放在一个对象里,针对这个对象做原子性操作。
CAS在JDK5中被J.U.C包广泛使用,在JDK6中被应用到synchronized的JVM实现中,因此在JDK5中J.U.C的效率是比synchronized高不少的,而到了JDK6,两者效率相差无几,而synchronized使用更简单、更不容易出错,所以其是专家组推荐的首选,除非需要用到J.U.C的特殊功能(如阻塞一段时间后放弃,而不是继续等待)。

7、synchronized 和 lock 有什么区别?

8、Hashtable 是怎么加锁的 ?

9、HashMap 的并发问题?

10、ConcurrenHashMap 介绍?1.8 中为什么要用红黑树?

11、AQS

12、如何检测死锁?怎么预防死锁?

13、Java 内存模型?

14、如何保证多线程下 i++ 结果正确?

15、线程池的种类,区别和使用场景?

16、分析线程池的实现原理和线程的调度过程?

17、线程池如何调优,最大数目如何确认?

18、ThreadLocal原理,用的时候需要注意什么?

19、CountDownLatch 和 CyclicBarrier 的用法,以及相互之间的差别?

20、LockSupport工具

21、Condition接口及其实现原理

22、Fork/Join框架的理解

23、分段锁的原理,锁力度减小的思考

24、八种阻塞队列以及各个阻塞队列的特性

25、多线程/并发中如何保证数据一致?

常见的锁:排它锁、乐观锁、悲观锁
排他锁:在进行写时,禁止一切的读和写;
处理并发问题有两种方式:第一是悲观锁(独占锁),第二是乐观锁(可重入锁)。
第一种锁独占锁,是一种阻塞情况最为严重的方式。就是给数据加上独占锁,其他线程想写这个数据的话就会被挂起,只有获取这个数据的线程才有权限写入这个数据,这样的话就存在大量线程挂起,和竞争锁的情况对于cpu是极大的消耗,效率低下。
第二种锁乐观锁,是给数据添加一个版本标识,每当有线程对其进行修改那么就把版本加一,这样当线程进行非原子操作的时候,一开始就保存了版本号,进行到修改数据的时候比较一下最新的版本号和久版本号是否一样,一样就修改不一样就重试(次数重试和时间重试两种)。
附:
独占锁-synchronized
独占锁是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。
乐观锁-CAS【compare and swap/set】
乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。
CAS有三个操作:当前内存中的值V,预期值A,更新后的值B,只有当A==V的时候,才会更新为B,否则nothing。

答案待补充... ...

JAVA面试题整理(2)-多线程/并发的更多相关文章

  1. 18家大厂Java面试题整理了350道(分布式+微服务+高并发)

    一.性能调优系列 1.Tomcat性能调优 JVM参数调优: -Xms 表示JVM初始化堆的大小, -Xmx表示JVM堆的最大值.这两个值的大小一般根据需要进行设置. 当应用程序需要的内存超出堆的最大 ...

  2. 尚学堂Java面试题整理

    博客分类: 经典分享   1. super()与this()的差别? - 6 -  2. 作用域public,protected,private,以及不写时的差别? - 6 -  3. 编程输出例如以 ...

  3. 【JAVA面试】java面试题整理(4)

    版权声明:转载请注明 https://blog.csdn.net/qq_33591903/article/details/83473779                               ...

  4. 北京Java笔试题整理

    北京Java笔试题整理 1.什么是java虚拟机?为什么ava被称作是"平台无关的编程语言? 答:Java虚拟机可以理解为一个特殊的"操作系统",只是它连接的不是硬件,而 ...

  5. Java面试题整理一(侧重多线程并发)

    1..是否可以在static环境中访问非static变量? 答:static变量在Java中是属于类的,它在所有的实例中的值是一样的.当类被Java虚拟机载入的时候,会对static变量进行初始化.如 ...

  6. java 面试题整理(不定期更新)

    一.Java基础 1.Java面向对象的三个特征与含义 三大特征是:封装.继承和多态. 封装是指将某事物的属性和行为包装到对象中,这个对象只对外公布需要公开的属性和行为,而这个公布也是可以有选择性的公 ...

  7. 《OD面试》Java面试题整理

    一.面试考察点 1 主语言本身 2 数据库 3 算法 4 Spring/SpringMVC/MyBatis 5 项目经验 1)项目涉及到的技术点深挖: (1)考察候选人技术深度  (2)看候选人遇到问 ...

  8. 金九银十,史上最强 Java 面试题整理。

    以下会重新整理所有 Java 系列面试题答案.及各大互联网公司的面试经验,会从以下几个方面汇总,本文会长期更新. Java 面试篇 史上最全 Java 面试题,带全部答案 史上最全 69 道 Spri ...

  9. 208道最常见的Java面试题整理(面试必备)

    适宜阅读人群 需要面试的初/中/高级 java 程序员 想要查漏补缺的人 想要不断完善和扩充自己 java 技术栈的人 java 面试官 具体面试题 下面一起来看 208 道面试题,具体的内容. 一. ...

随机推荐

  1. 【BZOJ5083】普及 单调栈+二分+RMQ

    [BZOJ5083]普及 Description 有一个长度为n的字符串,每一位只会是p或j.你需要取出一个子串S(从左到右或从右到左一个一个取出),使得 不管是从左往右还是从右往左取,都保证每时每刻 ...

  2. Exchange Powershell:Get-Counter (List connections to OWA )

    使用方法: Get-CASActiveUsers -server server1,server2 Get-CASMailbox | Get-CASActiveUsers $RPC = Get-Coun ...

  3. 【Python算法】渐进记法 与 性能测量工具cProfile

    对于某个比较简单的算法,我们有时候确实能够精确地分析出算法的复杂度. 比如算法复杂度为5n^2+10n+6,但是事实上并不需要这样,因为当n足够大时,可以忽略掉低阶项和最高次项的系数,因此就引出了“渐 ...

  4. uva656 Optimal Programs

    Optimal Programs As you know, writing programs is often far from being easy. Things become even hard ...

  5. Android 判断当前thread 是否是UI thread

    在Android 中判断当前的Thread是否是UI Thread 的方法: 1. if (Looper.myLooper() == Looper.getMainLooper()) { // Curr ...

  6. 即使关闭了nagle算法,粘包依旧存在

    JAVA高级架构 https://mp.weixin.qq.com/s?src=11&timestamp=1542107581&ver=1242&signature=OoktA ...

  7. closure--- 闭包与并行运算

      闭包有效的减少了函数所需定义的参数数目.这对于并行运算来说有重要的意义.在并行运算的环境下,我们可以让每台电脑负责一个函数,然后将一台电脑的输出和下一台电脑的输入串联起来.最终,我们像流水线一样工 ...

  8. Storm-源码分析-Stats (backtype.storm.stats)

    会发现, 现在storm里面有两套metrics系统, metrics framework和stats framework 并且在所有地方都是同时注册两套, 貌似准备用metrics来替代stats, ...

  9. php格式化输出数组

    写网页的时候经常需要在页面中打印数组,但格式特别难看,看看一个html神器吧<pre>标签,能非常标准的显示数组格式 使用的时候只需要这样打印你的数组就OK了,太好用了,神器! echo ...

  10. Python高级教程-多重继承

    多重继承 继承是面向对象编程的一个重要的方式,因为通过继承,子类可以扩展父类的功能. Animal类的层次设计,假设要实现以下4中动物: Dog - 狗狗: Bat - 蝙蝠: Parrot - 鹦鹉 ...