Java经典面试题汇总--多线程

目录
  • 1. 并行和并发有什么区别?
  • 2. 线程和进程的区别?
  • 3. 守护线程是什么?
  • 4. 实现多线程的方式有哪些?
  • 5. 说一下 runnable 和 callable 有什么区别?
  • 6. sleep() 和 wait() 有什么区别?
  • 7. 线程有哪些状态?
  • 8. notify()和 notifyAll()有什么区别?
  • 9. 线程的 run() 和 start() 有什么区别?
  • 10. 创建线程池有哪几种方式?
  • 11. 线程池中 submit() 和 execute() 方法有什么区别?
  • 12. Java 程序中怎么保证多线程的运行安全?
  • 13. 多线程中 synchronized 锁升级的原理是什么?
  • 14. 什么是死锁?
  • 15. 死锁的必要条件?怎么防止死锁?
  • 16. ThreadLocal 是什么?有哪些使用场景?
  • 17. 说一下 synchronized 底层实现原理?
  • 18. synchronized 和 volatile 的区别是什么?
  • 19. synchronized 和 Lock 有什么区别?
  • 20. 说一下 atomic 的原理?
  • 21. synchronized 和 ReentrantLock 区别是什么?
  • 22. LinkedBlockingQueue与ArrayBlockingQueue的区别?
  • 总结

1. 并行和并发有什么区别?

  • 并行:多个处理器或多核处理器同时处理多个任务。
  • 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。
  • 并发 = 两个队列和一台咖啡机。 并行 = 两个队列和两台咖啡机。

2. 线程和进程的区别?

一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度。

3. 守护线程是什么?

守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。 在 Java 中垃圾回收线程就是特殊的守护线程

4. 实现多线程的方式有哪些?

  • 继承Thread类:Java单继承,不推荐;
  • 实现Runnable接口:Thread类也是继承Runnable接口,推荐;
  • 实现Callable接口:实现Callable接口,配合FutureTask使用,有返回值;
  • 使用线程池:复用,节约资源;

5. 说一下 runnable 和 callable 有什么区别?

runnable 没有返回值,callable 可以拿到有返回值,callable 可以看作是 runnable 的补充

6. sleep() 和 wait() 有什么区别?

  • 两者都可以暂停线程的执行。
  • 类的不同:sleep() 来自 Thread,wait() 来自 Object。
  • 释放锁:sleep() 不释放锁;wait() 释放锁。
  • 用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。

7. 线程有哪些状态?

  • NEW 尚未启动
  • RUNNABLE 正在执行中
  • BLOCKED 阻塞的(被同步锁或者IO锁阻塞)
  • WAITING 永久等待状态
  • TIMED_WAITING 等待指定的时间重新被唤醒的状态
  • TERMINATED 执行完成

8. notify()和 notifyAll()有什么区别?

notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。 而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。

9. 线程的 run() 和 start() 有什么区别?

start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。 run() 可以重复调用,而 start() 只能调用一次。

10. 创建线程池有哪几种方式?

线程池创建有七种方式,最核心的是最后一种:

  • newSingleThreadExecutor():它的特点在于工作线程数目被限制为 1,操作一个无界的工作队列, 所以它保证了所有任务的都是被顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目;
  • newCachedThreadPool():它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用, 当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过 60 秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使用 SynchronousQueue 作为工作队列;
  • newFixedThreadPool(int nThreads):重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有 nThreads 个工作线程是活动的。 这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目 nThreads;
  • newSingleThreadScheduledExecutor():创建单线程池,返回 ScheduledExecutorService,可以进行定时或周期性的工作调度;
  • newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()类似, 创建的是个 ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程;
  • newWorkStealingPool(int parallelism):这是一个经常被人忽略的线程池,Java 8 才加入这个创建方法, 其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序;
  • ThreadPoolExecutor():是最原始的线程池创建,上面1-3创建方式都是对ThreadPoolExecutor的封装

11. 线程池中 submit() 和 execute() 方法有什么区别?

  • execute():只能执行 Runnable 类型的任务,无返回值
  • submit():可以执行 Runnable 和 Callable 类型的任务,有返回值

12. 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();
}

13. 多线程中 synchronized 锁升级的原理是什么?

ynchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id, 再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后, 如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。 锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗


14. 什么是死锁?

当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下, 就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。

15. 死锁的必要条件?怎么防止死锁?

  1. 互斥:一次只有一个进程可以使用一个资源。其他进程不能访问已分配给其他进程的资源。
  2. 占有且等待:当一个进程在等待分配得到其他资源时,其继续占有已分配得到的资源。
  3. 非抢占:不能强行抢占进程中已占有的资源。
  4. 循环等待:存在一个封闭的进程链,使得每个资源至少占有此链中下一个进程所需要的一个资源。

防止:

  • 死锁检测
  • 加锁顺序
  • 尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁。
  • 尽量使用 Java. util. concurrent 并发类代替自己手写锁。
  • 尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。 尽量减少同步的代码块。

16. ThreadLocal 是什么?有哪些使用场景?

ThreadLocal,即线程本地变量。如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地拷贝,多个线程操作这个变量的时候,实际是操作自己本地内存里面的变量,从而起到线程隔离的作用,避免了线程安全问题。常见的ThreadLocal使用场景为用来解决数据库连接、Session管理等。


17. 说一下 synchronized 底层实现原理?

synchronized 是由一对 monitorenter/monitorexit 指令实现的,monitor 对象是同步的基本实现单元。 在 Java 6 之前,monitor 的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。 但在 Java 6 的时候,Java 虚拟机 对此进行了大刀阔斧地改进,提供了三种不同的 monitor 实现, 也就是常说的三种不同的锁:偏向锁(Biased Locking)、轻量级锁和重量级锁,大大改进了其性能。

18. synchronized 和 volatile 的区别是什么?

  • volatile 是变量修饰符;synchronized 是修饰类、方法、代码段。
  • volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。
  • volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。

19. synchronized 和 Lock 有什么区别?

synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁。

synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。 通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。

20. 说一下 atomic 的原理?

atomic 主要利用 CAS (Compare And Wwap) 和 volatile 和 native 方法来保证原子操作, 从而避免 synchronized 的高开销,执行效率大为提升。

21. synchronized 和 ReentrantLock 区别是什么?

synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大, 但是在 Java 6 中对 synchronized 进行了非常多的改进。

主要区别如下:

  • ReentrantLock 使用起来比较灵活,但是必须有释放锁的配合动作;
  • ReentrantLock 必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁; ReentrantLock 只适用于代码块锁,而 synchronized 可用于修饰方法、代码块等。

22. LinkedBlockingQueue与ArrayBlockingQueue的区别?

队列大小有所不同,ArrayBlockingQueue是有界的初始化必须指定大小,而LinkedBlockingQueue可以是有界的也可以是无界的(Integer.MAX_VALUE),(而且不会初始化就占用一大片内存)对于后者而言,当添加速度大于移除速度时,在无界的情况下,可能会造成内存溢出等问题。

数据存储容器不同,ArrayBlockingQueue采用的是数组作为数据存储容器,而LinkedBlockingQueue采用的则是以Node节点作为连接对象的链表

由于ArrayBlockingQueue采用的是数组的存储容器,因此在插入或删除元素时不会产生或销毁任何额外的对象实例,而LinkedBlockingQueue则会生成一个额外的Node对象。这可能在长时间内需要高效并发地处理大批量数据的时,对于GC可能存在较大影响。

两者的实现队列添加或移除的锁不一样,ArrayBlockingQueue实现的队列中的锁是没有分离的,即添加操作和移除操作采用的同一个ReenterLock锁,而LinkedBlockingQueue实现的队列中的锁是分离的,其添加采用的是putLock,移除采用的则是takeLock,这样能大大提高队列的吞吐量,也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

两者的size都是强一致的。但是实现有区别,Array~使用全局锁      Linked~使用原子变量实现。

总结

本篇文章的内容就到这了,希望大家可以喜欢,也希望大家可以多多关注我们的其他精彩内容!

(0)

相关推荐

  • Java多线程和并发基础面试题(问答形式)

    本文帮助大家掌握Java多线程基础知识来对应日后碰到的问题,具体内容如下 一.Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和程序的单一进程.线程可以被称为轻量级进程.线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源. 2. 多线程编程的好处是什么? 在多线程程序中,多个线程被并发的执行以提高程序的效率,C

  • Java常见面试题之多线程和高并发详解

    volatile 对 volatile的理解 volatile 是一种轻量级的同步机制. 保证数据可见性 不保证原子性 禁止指令重排序 JMM JMM(Java 内存模型)是一种抽象的概念,描述了一组规则或规范,定义了程序中各个变量的访问方式. JVM运行程序的实体是线程,每个线程创建时 JVM 都会为其创建一个工作内存,是线程的私有数据区域.JMM中规定所有变量都存储在主内存,主内存是共享内存.线程对变量的操作在工作内存中进行,首先将变量从主内存拷贝到工作内存,操作完成后写会主内存.不同线程间

  • 15个高级Java多线程面试题及回答

    Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是一个非常受欢迎的话题,特别是电子交易发展方面相关的.他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者有足够的Java线程与并发方面的知识,因为候选人中有很多只浮于表面.用于直接面向市场交易的高容量和低延时的电子交易系统在本质上是并发的.下面这些是我在不同时间不同地点喜欢问的Jav

  • 2018版java多线程面试题集合及答案

    java多线程面试题整理及答案,供大家参考,具体内容如下 1.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速.比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒.Java在语言层面对多线程提供了卓越的支 持,它也是一个很好的卖点. 2.线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务.不同的进程使用

  • 15个顶级Java多线程面试题(附答案)

    在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是一个非常受欢迎的话题,特别是电子交易发展方面相关的.他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者有足够的Java线程与并发方面的知识,因为候选人中有很多只浮于表面.用于直接面向市场交易的高容量和低延时的电子交易系统在本质上是并发的.下面这些是我在不同时间不同地点喜欢问的Java线程问题.我没有提供答

  • Java经典面试题汇总--多线程

    目录 1. 并行和并发有什么区别? 2. 线程和进程的区别? 3. 守护线程是什么? 4. 实现多线程的方式有哪些? 5. 说一下 runnable 和 callable 有什么区别? 6. sleep() 和 wait() 有什么区别? 7. 线程有哪些状态? 8. notify()和 notifyAll()有什么区别? 9. 线程的 run() 和 start() 有什么区别? 10. 创建线程池有哪几种方式? 11. 线程池中 submit() 和 execute() 方法有什么区别? 1

  • Java经典面试题汇总:Spring

    目录 1. 什么是Spring? 有哪些优点? 2. 什么是 AOP? 3. 什么是 IOC? 4. 什么是 DI? 5. Spring 有哪些核心模块? 6. Spring 常用的注入方式有哪些? 7. Spring 中的 Bean 是线程安全的吗? 8. Spring中Bean的作用域有哪些? 9. @Qualifier 注解 10. @Resource与@Autowired注解的区别? 11. Spring底层两种动态代理实现原理及区别? 12. Spring 事务实现方式有哪些? 13.

  • Java经典面试题汇总:JVM

    目录 1. 说一下 JVM 的主要组成部分?及其作用? 2. 说一下 JVM 运行时数据区? 3. 说一下堆栈的区别? 4. 解释内存中的栈(stack).堆(heap)和静态区(static area)的用法 5. 类的生命周期 6. Java对象创建过程 7. 怎么判断对象是否可以被回收? 8. 什么是类加载器? 9. 什么是双亲委派模型? 10. 说一下类装载的执行过程? 11. Java 中都有哪些引用类型? 12. JVM 有哪些垃圾回收算法? 13. JVM 有哪些垃圾回收器? 14

  • Java经典面试题汇总:Spring Boot

    目录 1. 什么是 Spring Boot? 2. 为什么要用 Spring Boot? 3. Spring Boot 核心配置文件是什么? 4. Spring Boot 提供了哪些常用的 Starter Project Options? 5. 如何快速构建一个Spring Boot项目? 6. Spring Boot默认的内置Web服务器是什么? 7. Spring Boot常用注解及其作用? 8. 如何使用配置文件通过 Spring Boot 配置特定环境的配置? 总结 1. 什么是 Spr

  • Java经典面试题汇总:Spring MVC

    目录 1. 什么是Spring MVC ? 2. Spring MVC 有哪些组件? 3. 说一下 Spring MVC 运行流程? 4. Spring MVC的优点: 5. @RequestMapping 的作用是什么? 6. 如果在拦截请求中,我想拦截get方式提交的方法,怎么配置? 7. SpringMVC常用的注解有哪些? 8. SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代? 9. Spring MVC和Struts2的区别有哪些? 10. 怎么样在方法里面得到Re

  • Java经典面试题汇总:异常

    目录 1. Java的异常机制 2. Java如何自定义异常? 3. throw 和 throws 的区别? 4. Java 中被检查的异常和不受检查的异常有什么区别? 5. final.finally.finalize 有什么区别? 6. try-catch-finally 中哪个部分可以省略? 7. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 8. Java 中什么时候使用断言? 9. 运行时异常与一般异常有何异同? 10.

  • Java经典面试题汇总:Java Web

    目录 1. JSP 和 servlet 有什么区别? 2. 什么是Tomcat? 3. Tomcat容器是如何创建Servlet类实例?用到了什么原理? 4. 拦截器和过滤器的区别? 5.说一下 JSP 的 4 种作用域? 6. JSP 有哪些内置对象?作用分别是什么? 7. Servlet的生命周期 8. session 和 cookie 有什么区别? 9. 说一下 session 的工作原理? 10. 如果客户端禁止 cookie 能实现 session 还能用吗? 11. JSP工作原理?

  • Java经典面试题汇总:Mybatis

    目录 1. MyBatis 中 #{}和 ${}的区别是什么? 2. MyBatis 有几种分页方式? 3. MyBatis 逻辑分页和物理分页的区别是什么? 4. MyBatis 是否支持延迟加载?延迟加载的原理是什么? 5. 说一下 MyBatis 的一级缓存和二级缓存? 6. MyBatis 有哪些执行器(Executor)? 7. MyBatis 分页插件的实现原理是什么? 8. MyBatis如何返回主键? 9. Xml映射文件中,除了常见的select|insert|update|d

  • Java经典面试题汇总:网络编程

    目录 1. HTTP 响应码 301 和 302 代表的是什么?有什么区别? 2. 简单说一下http协议? 3. HTTP与HTTPS的区别? 4. HTTP协议下客户端请求报文是什么? 5. HTTP协议服务器响应报文有哪些? 6. HTTP协议中的请求方法有哪些? 7. 常见的HTTP状态码有哪些? 8. forward 和 redirect 的区别? 9. 简述 tcp 和 udp的区别? 10. TCP 为什么要三次握手,两次不行吗?为什么? 11. 说一下 TCP 粘包是怎么产生的?

  • Java经典面试题最全汇总208道(四)

    目录 前言 126.Spring 框架中的单例 Beans 是线程安全的么? 127.请解释 Spring Bean 的自动装配? 129.什么是 Spring Batch? 130.spring mvc 和 struts 的区别是什么? 131.请举例解释@Required 注解? 132.Spring常用注解 133.项目中是如何实现权限验证的,权限验证需要几张表 134.谈谈controller,接口调用的路径问题 135.如何防止表单重复提交 136.Spring中都应用了哪些设计模式

随机推荐