1、开发过程中,什么时候考虑使用多线程

异步处理时候需要使用多线程:比如记录日志,发短信

数据的分析,数据迁移的时候,可以用多线程,比如hadoop中mapreduce计算时候,可以增加分区

  • 发短信,app消息提醒等场景。在营销活动中,用户中奖了,需要短信提醒。可以将发短信的业务放入到另外一个线程中执行,用户晚一会收到短信对整体的业务流程也不会受到影响,反而提升了用户体验
  • 推送场景:比如有一个业务场景,有一个报表监管系统,当收到数据之后,需要将这些数据发送给第三方的监管系统,数据量有百万之多,一条数据按照一秒计算,那需要经过百万秒,200多个小时才能处理完,考虑引入多线程进行并发操作,降低数据推送时间,提高数据推送的实时性

2、java线程创建的方式

1、继承Thread类  2、实现runnable接口 3、继承callable接口 4、基于线程池创建线程

3、为什么用线程池,解释下线程池参数

线程池本质上是一种池化技术,而池化技术是一种资源复用的思想,为了减少线程频繁创建和销毁带来的性能开销,因为线程创建会涉及到CPU上下文切换、内存分配等工作。线程池本身会有参数来控制线程创建的数量,这样就可以避免无休止的创建线程带来的资源利用率过高的问题,起到了资源保护的作用。
线程池参数七大参数

  • corePoolsize  核心线程数:正常情况下创建的工作的线程数,这些线程创建后并不会立马消除,一种常驻住线程
  • maxinumPoolSize 最大线程数:表示允许创建的最大线程数
  • keepAliveTime 表示超出线程数之外的线程数空闲存活时间
  • unit     keepAliveTime 的计量单位
  • workQueue:用来存放待执行任务的队列
  • threadFactory:创建一个线程工厂用来生产线程,可以用来设定线程名
  • handler:任务拒绝策略

4、Java线程池的工作流程

一个新的任务提交到线程池时:

  • 线程池判断核心线程池里的核心线程是否都在执行任务。 如果不是,让空闲的核心线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。
  • 线程池判断阻塞队列是否已满。 如果阻塞队列没有满,则将新提交的任务存储在阻塞队列中。如果阻塞队列已满,则进入下个流程。
  • 判断线程池里的线程数量是否小于最大线程数量(看线程池是否满了)。 如果小于,则创建一个新的工作线程(非核心线程,并给它设置超时时间,当我们处理完这些任务,无需手动销毁这个非核心线程,超时自动销毁)来执行任务。如果已满,则交给拒绝策略来处理这个任务。

5、线程池拒绝策略及任务队列

四种拒绝策略

  • AbortPolicy 直接丢弃任务,抛出RejectedExecution异常,是默认策略
  • DiscardPolicy  直接丢弃任务,但不抛出异常
  • DiscardOldestPolicy 丢弃等待队列中最旧的任务,并执行当前任务
  • CallerRunsPolicy  用调用者所在的线程处理任务

四种任务队列

  • 直接提交的任务队列,设置为SynchronousQueue队列,SynchronousQueue是一个特殊的BlockingQueue,它没有容量,每执行一个插入操作就会阻塞。
  • 有界的任务队列  如ArrayBlockingQueue
  • 无界的任务队列 如LinkedBlockingQueue
  • 优先任务队列 如PriorityBlockingQueue

6、Java线程池如何合理配置核心线程数?如何去设置呢?

  1. CPU 密集型任务:比如像加解密,压缩、计算等一系列需要大量耗费 CPU 资源的任务,大部分场景下都是纯 CPU 计算。因此,对于 CPU 密集型的计算场景,理论上线程的数量 = CPU 核数就是最合适的,不过通常把线程的数量设置为CPU 核数 +1,会实现最优的利用率。
  2. IO 密集型任务:比如像 MySQL 数据库、文件读写、网络通信等任务,这类任务不会特别消耗 CPU 资源,但是 IO 操作比较耗时,会占用比较多时间。线程数 = CPU 核心数 * (1 + IO 耗时/ CPU 耗时) 或是 IO密集型:核心线程数 = CPU核数 * 2

7、请详细描述一下线程从创建到死亡的几种状态都有哪些?

  • 新建( new ):新创建了一个线程对象。
  • 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
  • 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
  • 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。
  • 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。

8 、线程池都有哪些状态?

  • RUNNING:这是最正常的状态,接受新的任务,处理等待队列中的任务。
  • SHUTDOWN:不接受新的任务提交,但是会继续处理等待队列中的任务。
  • STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。
  • TIDYING:所有的任务都销毁了,workCount 为 0,线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()。
  • TERMINATED:terminated()方法结束后,线程池的状态就会变成这个。

9、sleep()和wait()区别

sleep()来自thread,wait()来自object();

sleep()不释放锁,wait释放锁

sleep()时间到了会自动恢复,wait()可以使用notify()直接唤醒

10、说说java内存模型

java内存模型(JMM)是线程间通信的控制机制.JMM定义了主内存和线程之间抽象关系。线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。

11、在 Java 程序中怎么保证多线程的运行安全?

方法一:使用安全类,比如 Java. util. concurrent 下的类。

方法二:使用自动锁 synchronized。

方法三:使用手动锁 Lock。 手动锁 Java 示例代码如下:

Lock lock = new ReentrantLock();
lock. lock();
try {
System. out. println("获得锁");
} catch (Exception e) {
// TODO: handle exception
} finally {
System. out. println("释放锁");
lock. unlock();
}

12、JAVA如何在两个线程之间共享数据

Java 里面进行多线程通信的主要方式就是共享内存的方式,共享内存主要的关注点有两个:可见性和有序性原子性。Java 内存模型(JMM)解决了可见性和有序性的问题,而锁解决了原子性的问题,理想情况下我们希望做到“同步”和“互斥”。有以下常规实现方法:
将数据抽象成一个类,并将数据的操作作为这个类的方法
1. 将数据抽象成一个类,并将对这个数据的操作作为这个类的方法,这么设计可以很容易做到同步,只要在方法上加“synchronized“。

2. 将 Runnable 对象作为一个类的内部类,共享数据作为这个类的成员变量,每个线程对共享数据的操作方法也封装在外部类,以便实现对数据的各个操作的同步和互斥,作为内部类的各个 Runnable 对象调用外部类的这些方法。

java中多线程常见面试题相关推荐

  1. 「高级java工程师」常见面试题及其答案(持续更新)

    「java工程师」常见面试题及其答案请见: 「java工程师」常见面试题及其答案(持续更新)_好人老李的博客-CSDN博客 目录 java基础 常用的 jvm 调优方法? OOM的常见场景及其原因.解 ...

  2. java中级程序员面试题_中级Java程序员常见面试题汇总

    下面是一些中级Java程序员常见面试题汇总,你可以用它来好好准备面试. 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器 ...

  3. 「java工程师」常见面试题及其答案(持续更新)

    「高级java工程师」常见面试题及其答案: 「高级java工程师」常见面试题及其答案(持续更新)_好人老李的博客-CSDN博客 目录 java基础 面向对象与面向过程的区别? JRE.JDK.JVM的 ...

  4. Java后端工程师常见面试题

    以下是整理的Java后端工程师常见面试题,希望有助于找工作: 1,对Java集合框架的理解.ArrayList和LinkedList的区别和优缺点,以及使用场景.扩容因子了解吗?分别是多少. Java ...

  5. 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!

    本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习 面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...

  6. java线程池面试题有哪些?java线程池常见面试题

    进行java面试的过程中,java线程池是必问的面试题目,因为这是java的重点知识,也是在java工作中经常会遇到的,那java线程池面试题有哪些?下面来我们就来给大家讲解一下java线程池常见面试 ...

  7. Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)

    Java多线程面试题以及答案整理[最新版]Java多线程高级面试题大全(2021版),发现网上很多Java多线程面试题都没有答案,所以花了很长时间搜集,本套Java多线程面试题大全,汇总了大量经典的J ...

  8. java多线程常用面试_java的多线程常见面试题

    并行和并发有什么区别? (推荐学习:java常见面试题) 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生. 并行是在不同实体上的多个事件,并发是在同一实体上的多个事 ...

  9. 【面试题系列】Java多线程常见面试题

    目录 序言 问题 1.Java中的线程有哪些状态,它们之间是如何转换的? 2.什么是Java中的线程安全?怎么实现 3.Java中线程的创建方法有哪些 3.1 继承Thread类并覆盖run()方法 ...

  10. Java初级工程师常见面试题

    整理一下自己所经历的高频面试题目.对于一个初级java开发人员的面试,面试时间一般为30~40分钟,有短点的,先写一张笔试卷子,然后面试20分钟,也有长一些的,我最长的一次面试将近2个小时,最后一轮纯 ...

最新文章

  1. find the most comfortable road
  2. 数据库事务的四大特征
  3. 每日程序C语言39-不带头结点的头插法创建链表
  4. ROS和OpenCV的对接cv_bridge
  5. gwt api_使用RequestFactory API进行Spring GWT集成
  6. 计算机内部运算的部件是什么意思,运算器是执行什么和什么运算的部件
  7. 畅想未来计算机的绘画作品小学生,畅想未来儿童画绘画作品大全
  8. 员工需签军令状放弃年终奖?传小米推出特殊激励计划 官方回应...
  9. 博图买什么样配置的笔记本_3dsmax需要什么样的笔记本配置?
  10. win服务器自动发邮件,asp.net基于windows服务实现定时发送邮件的方法
  11. 按值对对象属性进行排序
  12. HBuilderx中编译sass文件
  13. 公交换乘 详解(C++)
  14. JMETER录制脚本,脚本增强,参数化,作用域和执行顺序
  15. Python已知经纬度求两点距离
  16. ddgr:一个从终端搜索 DuckDuckGo 的命令行工具
  17. 三星android 安卓版本怎么升级包,三星A70官方安卓9固件系统线刷升级更新包:BRI-A7050ZHU3ASJ1...
  18. 计算机无法识别佳能5d2,佳能相机连接后电脑显示无法识别
  19. 微信官方:“微信号能修改了!”你有多想修改微信号?
  20. target=_blank和target=_black

热门文章

  1. 计算机硬盘介绍,硬盘简介 - 硬盘使用知识大全(1)
  2. arm+linux书籍
  3. 【图像分割】基于马尔可夫随机场实现图像分割附matlab代码
  4. 爬取mzi.com妹子图片网站(requests库)
  5. 计算机运行时内存会超吗,我们不曾深纠的电脑技术 篇一:我们为什么要对内存进行超频?...
  6. 操作简单、功能务实——四维星软件
  7. PR菜鸟入门 -- PR下载安装
  8. Linux安装阿里yum源
  9. WPF高级教程(三)XAML
  10. 电视盒子刷鸿蒙系统,家里的智能电视能装鸿蒙系统吗?鸿蒙系统有哪些优势?...