并发-Java 并发基础常见面试题总结

本文深入探讨了进程和线程的概念,分析了它们之间的关系、区别及优缺点,并详细讲解了并发与并行的区别,线程死锁的原理与预防方法,以及sleep()和wait()方法的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 什么是线程和进程?

1.1. 何为进程?

1.2. 何为线程?

2. 请简要描述线程与进程的关系,区别及优缺点?

2.1. 图解进程和线程的关系

2.2. 程序计数器为什么是私有的?

3. 说说并发与并行的区别?

8. 什么是线程死锁?如何避免死锁?

8.1. 认识线程死锁

8.2. 如何避免线程死锁?

9. 说说 sleep() 方法和 wait() 方法区别和共同点?


1. 什么是线程和进程?

1.1. 何为进程?

程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。

1.2. 何为线程?

操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。

(对应到Java里面就是线程私有程序计数器、虚拟机栈、本地方法栈)。

 

 

2. 请简要描述线程与进程的关系,区别及优缺点?

2.1. 图解进程和线程的关系

从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的方法区 (JDK1.8 之后的元空间)资源

但是每个线程有自己的程序计数器虚拟机栈 和 本地方法栈

线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响

2.2. 程序计数器为什么是私有的?

程序计数器主要有下面两个作用:

  • 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
  • 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。

(需要注意的是,如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。 )

所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置

 

3. 说说并发与并行的区别?

  • 并发: 同一时间段,多个任务都在执行 (单位时间内不一定同时执行);
  • 并行: 单位时间内,多个任务同时执行。

 

8. 什么是线程死锁?如何避免死锁?

8.1. 认识线程死锁

学过操作系统的朋友都知道产生死锁必须具备以下四个条件:

  1. 互斥条件:该资源任意一个时刻只由一个线程占用。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:线程已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

8.2. 如何避免线程死锁?

  • 破坏不剥夺条件

占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。

使用tryLock()

  • 破坏循环等待条件

按顺序申请锁

  • 查看线程转储ThreadDump

 

9. 说说 sleep() 方法和 wait() 方法区别和共同点?

  • 两者最主要的区别在于:sleep 方法没有释放锁,而 wait 方法释放了锁 。
  • 两者都可以暂停线程的执行。
  • Wait 通常被用于线程间交互/通信,sleep 通常被用于暂停执行。
  • wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify() 或者 notifyAll() 方法。sleep() 方法执行完成后,线程会自动苏醒。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值