开篇介绍

大家好,公众号【Java极客思维】近期会整理一些Java高频面试题分享给小伙伴,也希望看到的小伙伴在找工作过程中能够用得到!本章节主要针对Java一些多线程高频面试题进行分享。

Q1:

乐观锁 和 悲观锁

乐观锁:

乐观锁(Optimistic Locking)其实是一种思想。相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。

悲观锁:

Java在JDK1.5之前都是靠 synchronized 关键字保证同步的,这种通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有共享变量的锁,都采用独占的方式来访问这些变量。独占锁就是一种悲观锁,所以可以说:synchronized是悲观锁 。

Q2:

synchronized内置锁

用处:

synchronized作为线程同步的关键字,设计到锁的概念,Java内置锁是一个互斥锁,这就说明最多只有一个线程能够获得该锁,例如线程A 和 线程B,如果线程A尝试去获得线程B的内置锁,则线程A必须等待或者阻塞,直到线程B释放这个锁为止;如果线程B永不释放这个锁,那么线程A将永远处于等待或者阻塞状态。Java的对象锁和类锁在锁的概念上,与内置锁几乎是一致的,但是对象锁和类锁的区别是非常大的。

对象锁:

synchronized关键字修饰非静态方法用synchronized(this)作为同步代码块用synchronized(非this对象)的用法,锁的是对象,线程想要执行对应的同步代码,需要先获得对象锁。

类锁:

synchronized修饰静态方法、用synchronized(类.class)的用法,锁的是类,线程想要执行对应的同步代码,需要先获得对象锁。

对象锁:锁的是类的对象实例;

类锁:锁的是每个类的Class对象,每个类的Class对象在虚拟机中只有一个,所以类锁也只有一个。

Q3:

乐观锁一定就是好的吗?

乐观锁避免了悲观锁独占对象的现象,同时也提高了并发性能,但是也有以下几个缺点:

1. 乐观锁只能保证一个共享变量的原子操作。如果多一个或者几个变量,乐观锁将变得力不从心;

(但互斥锁能轻易解决,不管对象数量多少以及对象颗粒度大小。)

2. 长时间自旋可能导致开销大。假如CAS长时间不成功就会一直自旋,会给CPU带来非常巨大的开销

3. ABA问题。CAS的核心思想是通过对比内存值与预期值是否一致而判断内存值是否被改动过,但这个判断逻辑不够严谨,例如:假如A同学倒了一杯水放桌子上,然后有事去忙,此时B同学经过,看到桌子上的水,然后喝了半杯,喝完后再将水打满,实际看起来还是一杯水,但是这杯水已经不是A同学的那一杯水了,且实际上水是已经被B同学改过了,这种情况对依赖过程值的情景的运算结果影响很大。

解决的方案:通过引入版本号,每次变量更新都把版本号加1.

Q4:

线程池的启动策略?

线程池的执行过程.png

1. 线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过就算队列里面有任务,线程池也不会马上执行它们。

2. 当调用 execute() 方法添加一个任务时,线程池会做如下判断:

  • 如果正在运行的线程数量小于 corePoolSize ,那么马上创建线程运行这个任务;

  • 如果正在运行的线程数量大于或等于 corePoolSize , 那么将这个任务放入队列;

  • 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize ,那么还是要创建线程运行这个任务;

  • 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize ,那么线程池会抛出异常,告知调用者"我不能再接受任务了"。

3. 当一个线程完成任务时,它会从队列中取下一个任务来执行。

4. 当一个线程无事可做,超过一定的时间 (keepAliveTime) 时,线程池会进行判断,如果当前运行的线程数大于 corePoolSize ,那么这个线程就会被停掉。所以线程池的所有任务完成后,它最终将会收缩到 corePoolSize 大小。

明天,会介绍多线程一些深入的知识,长按二维码关注我吧~

祝大家都能拿到心仪的offer!


点关注、不迷路

如果觉得文章不错,欢迎关注点赞收藏,你们的支持是我创作的动力,感谢大家。

如果文章写的有问题,请不要吝啬,欢迎留言指出,我会及时核查修改。

如果你还想更加深入的了解我,可以微信搜索「Java极客思维」进行关注。每天8:00准时推送技术文章,让你的上班路不在孤独,而且每月还有送书活动,助你提升硬实力!

Java面试专题-多线程篇(2)- 锁和线程池的更多相关文章

  1. Java面试专题-多线程(3)-原子操作

  2. Java面试专题-基础篇(1)

  3. Java面试专题-集合篇(2)

  4. JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

    JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...

  5. 【JAVA秒会技术之秒杀面试官】秒杀Java面试官——集合篇(一)

    [JAVA秒会技术之秒杀面试官]秒杀Java面试官——集合篇(一) [JAVA秒会技术之秒杀面试官]JavaEE常见面试题(三) http://blog.csdn.net/qq296398300/ar ...

  6. Java多线程学习(八)线程池与Executor 框架

    目录 历史优质文章推荐: 目录: 一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 2.3 Executor 框架的使用示意图 ...

  7. Java第三阶段学习(七、线程池、多线程)

    一.线程池 1.概念: 线程池,其实就是一个容纳多个线程的容器,其中的线程可以重复使用,省去了频繁创建线程对象的过程,无需反复创建线程而消耗过多资源,是JDK1.5以后出现的. 2.使用线程池的方式- ...

  8. Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>

    1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...

  9. Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析

    目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...

随机推荐

  1. 手写Koa.js源码

    用Node.js写一个web服务器,我前面已经写过两篇文章了: 第一篇是不使用任何框架也能搭建一个web服务器,主要是熟悉Node.js原生API的使用:使用Node.js原生API写一个web服务器 ...

  2. 5分钟GET我使用Github 5 年总结的这些骚操作!

    我使用 Github 已经有 5 年多了,今天毫无保留地把自己觉得比较有用的 Gihub 小技巧送给关注 JavaGuide 的各位小伙伴. 这篇文章肝了很久,就挺用心的,大家看内容就知道了. 如果觉 ...

  3. Android 视频播放器 NurVideoPlayer ()

    我在实战项目中用了它. 更新了2.x.x版本ijkplayer的封装 支持屏幕滑动--滑动时间,亮度,声音,进度,支持全屏-单屏,双击暂停--继续,锁定屏幕,支持HTTP和https,也可以控制声道( ...

  4. VS中Dev控件在工具箱里的不见的解决办法

    出现问题:调整了VS中Dev控件后(以免生成程序每次都要在客户机上面注册dev),之前安装的DEV控件在vs工具箱中消失了,重装可以解决,但是太费时间了,检测dev自带的设置,找到了解决办法. 解决办 ...

  5. 交换机基于接口划分VLAN(汇聚层设备作为网关)

    组网图形 简介 划分VLAN的方式有:基于接口.基于MAC地址.基于IP子网.基于协议.基于策略(MAC地址.IP地址.接口).其中基于接口划分VLAN,是最简单,最常见的划分方式,如接入层设备作为网 ...

  6. Layui弹出层详解

    今天空了学习一下弹出层 还是一步步展示把 首先,layer可以独立使用,也可以通过Layui模块化使用.我个人一直是用的模块化的 所以下面素有的都是基于模块化的. 引入好相关文件就可以开始啦  今天放 ...

  7. canvas基础[二]教你编写贝塞尔曲线工具

    贝塞尔曲线 bezierCurveTo 在线工具 https://canvature.appspot.com/ [感觉这个好用一些] https://blogs.sitepointstatic.com ...

  8. POSIX条件变量

    条件变量: 当一个线程互斥的访问某个变量时,它可能发现其他线程改变状态之前,它什么都做不了例如:一个线程访问队列时,发现队列为空,它只能等待,直到其他线程将一个节点添加到队列中,这种情况就需要使用条件 ...

  9. 加解密 C语言实现

    1.加密的基本原理 加密分为对称加密和非对称加密,对称加密就是加密方和解密放用同一个密钥. 加密是分组加密,即将明文数据分成多个密钥大小的块,依次和密钥运算,输出密文. padding,由于加密需要分 ...

  10. ceph luminous版本限制osd的内存使用

    引言 ceph自从到了L版本以后,L版本的启用,对性能本身有了极大的提高,一直对这个比较不放心的就是内存的占用,刚开始的时候记得大量dd就可以把内存搞崩掉,这个应该是内部的设计逻辑需要更多的内存的占用 ...