分享50道Java多线程高频面试题,面试不用愁

1. 什么是进程?

是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。

2. 什么是线程?

线程是操作系统能够进行运算调度的最小单位。

它被包含在进程之中,是进程中的实际运作单位。

一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

3. 进程和线程的区别?

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。

进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。

线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

4. 多线程和单线程有什么区别?

单线程程序:程序执行过程中只有一个有效操作的序列,不同操作之间都有明确的执行先后顺序,容易出现代码阻塞

多线程程序:有多个线程,线程间独立运行,能有效地避免代码阻塞,并且提高程序的运行性能

5. 为什么要使用多线程?

  1. 使用多线程可以减少程序的响应时间。 在单线程的情况下,如果某个程序很耗时或者陷入长时间等待(如等待网络响应),此时程序将不会相应鼠标和键盘等操作,使用多线程后,可以把这个耗时的线程分配到一个单独的线程去执行,从而是程序具备了更好的交互性。
  2. 与进程相比,线程的创建和切换开销更小。 由于启动一个新的线程必须给这个线程分配独立的地址空间,建立许多数据结构来维护线程代码段、数据段等信息,而运行于同一个进程内的线程共享代码段、数据段,线程的启动或切换的开销就比进程要少很多。同时多线程在数据共享方面效率非常高。
  3. 多CPU或多核心计算机本身就具有执行多线程的能力。 如果使用单个线程,将无法重复利用计算机资源,造成资源的巨大浪费。因此在多CPU计算机上使用多线程能提高CPU的利用率。
  4. 使用多线程能简化程序的结构,使用程序便于理解和维护。 一个非常复杂的进程可以分成多个线程来执行。

6. 什么是线程安全?

当多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替运行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获取正确的结果,那这个对象是线程安全的。 ——<<深入Java虚拟机>>

7. 为何要使用线程同步?

Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突。

因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。

8. 如何确保线程安全?

  • 对非安全的代码进行加锁控制
  • 使用线程安全的类
  • 多线程并发情况下,线程共享的变量改为方法级的局部变量

9. 什么是原子操作?

检查数值、改变数值,以及可能发生的睡眠操作均作为单一的、不可分割的原子操作完成。

分享50道Java多线程高频面试题,面试不用愁_第1张图片

10. Java内存模型是什么?

1、Java中所有变量都储存在主存中,对于所有线程都是共享的(因为在同一进程中),每个线程都有自己的工作内存或本地内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,而线程之间无法相互直接访问,变量传递均需要通过主存完成,但是在程序内部可以互相调用(通过对象方法),所有线程间的通信相对简单,速度也很快。

分享50道Java多线程高频面试题,面试不用愁_第2张图片

2、进程间的内部数据和状态都是相互完全独立的,因此进程间通信大多数情况是必须通过网络实现。线程本身的数据,通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。

3、CPU对于各个线程的调度是随机的(分时调度),在Java程序中,JVM负责线程的调度。 线程调度是指按照特定的机制为多个线程分配CPU的使用权,也就是实际执行的时候是线程,因此CPU调度的最小单位是线程,而资源分配的最小单位是进程。

11. Java中堆和栈有什么不同?

栈:在函数中定义的基本类型的变量和对象的引用变量都是在函数的栈内存中分配。

堆:堆内存用于存放由new创建的对象和数组。

从通俗化的角度来说,堆是用来存放对象的,栈是用来存放执行程序的

12. JVM中哪个参数是用来控制线程的栈堆栈小的

-Xss参数用来控制线程的堆栈大小。

13. 什么是竞态条件?你怎样发现和解决竞争?

当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。

在临界区中使用适当的同步就可以避免竞态条件。

界区实现方法有两种,一种是用synchronized,一种是用Lock显示锁实现。

14. 线程安全的级别

不可变

不可变的对象一定是线程安全的,并且永远也不需要额外的同步。

Java类库中大多数基本数值类如Integer、String和BigInteger都是不可变的。

无条件的线程安全

由类的规格说明所规定的约束在对象被多个线程访问时仍然有效,不管运行时环境如何排列,线程都不需要任何额外的同步。

如 Random 、ConcurrentHashMap、Concurrent集合、atomic

有条件的线程安全

有条件的线程安全类对于单独的操作可以是线程安全的,但是某些操作序列可能需要外部同步。

有条件线程安全的最常见的例子是遍历由 Hashtable 或者 Vector 或者返回的迭代器

非线程安全(线程兼容)

线程兼容类不是线程安全的,但是可以通过正确使用同步而在并发环境中安全地使用。

如ArrayList HashMap

线程对立

线程对立是那些不管是否采用了同步措施,都不能在多线程环境中并发使用的代码。

如如System.setOut()、
System.runFinalizersOnExi

你可能感兴趣的:(面试,java,经验分享)