返回
技术指南:多线程面试题 - 上篇(线程基本概念 + 线程池)
见解分享
2023-12-02 19:38:21
多线程面试指南:入门
线程的基本概念
线程是进程中的执行单元,与进程共享相同的代码和数据空间,但拥有自己的执行栈和程序计数器。线程允许程序同时执行多个任务,从而提高效率和响应能力。
进程与线程的区别
特性 | 线程 | 进程 |
---|---|---|
资源分配 | 与其他线程共享进程资源(如内存、文件) | 拥有自己的资源 |
调度 | 由同一个进程中的其他线程调度 | 由操作系统调度 |
开销 | 创建和销毁成本较低 | 创建和销毁成本较高 |
独立性 | 无法独立于进程存在 | 独立于进程存在 |
线程的状态
- 新建 (New):刚创建,尚未启动
- 可运行 (Runnable):准备执行
- 运行 (Running):正在执行
- 等待 (Waiting):等待资源或事件
- 阻塞 (Blocked):无法继续执行,直到满足特定条件
- 终止 (Terminated):线程已完成执行或异常终止
线程池
线程池是一种管理线程生命周期和资源分配的机制。它预先创建一定数量的线程并将其放入池中,以满足应用程序的并发需求,避免频繁创建和销毁线程带来的开销。
线程池的优点
- 提高性能:避免频繁创建和销毁线程的开销。
- 减少资源消耗:线程池可以控制同时活动的线程数量,防止系统因线程过多而耗尽资源。
- 提高可伸缩性:通过动态调整线程池大小,可以适应不同负载的情况。
线程池的实现方式
- 有界队列:限制了可以同时进入池中的线程数量。
- 无界队列:允许无限数量的线程进入池中,但可能会导致资源耗尽。
- 工作窃取算法:允许线程从其他线程那里窃取任务,提高并行性。
锁
锁是一种同步机制,用于协调多个线程对共享资源的访问,防止同时修改造成数据不一致。
锁的类型
- 互斥锁 (Mutex):保证同一时间只有一个线程可以访问共享资源。
- 读写锁:允许多个线程同时读取共享资源,但仅允许一个线程写入。
- 条件变量:用于线程之间的等待和唤醒。
同步
同步是一种机制,用于确保多个线程对共享资源的访问是有序且协调的。
同步方法
- 锁:使用锁可以防止多个线程同时访问共享资源。
- 信号量:限制同时可以访问共享资源的线程数量。
- 屏障:确保所有线程都到达某个点后才能继续执行。
通信
线程间通信可以通过以下方式实现:
- 共享内存:使用全局变量或数据结构在不同线程之间共享数据。
- 消息传递:使用消息队列或管道的消息传递机制进行通信。
- 信号:使用信号和事件等机制通知线程某些事件已经发生。
并发
并发是指多个计算任务同时执行,但它们并不一定在同一个时间点执行。
并发与并行的区别
- 并发:多个任务同时执行,但不一定同时发生。
- 并行:多个任务真正同时发生,需要多核 CPU 或多处理器。
并发编程的挑战
- 数据竞争:多个线程同时访问共享资源,可能导致数据不一致。
- 死锁:线程因资源依赖而无限等待,导致系统瘫痪。
- 饥饿:某些线程长期无法获得资源,导致其无法执行。
常见问题解答
- 什么是轻量级进程 (LWP)?
LWP是一种线程实现,它与内核线程不同,不会映射到操作系统级线程。LWP更轻量级,创建和销毁成本更低。 - 什么是线程局部存储 (TLS)?
TLS是每个线程都可以访问的私有存储区域。它允许线程存储自己的数据,而不必担心其他线程访问它。 - 如何避免死锁?
避免死锁的一个策略是使用死锁检测和恢复机制。另一个策略是确保线程按照相同的顺序获取资源。 - 为什么线程池比手动创建和销毁线程更好?
线程池提供了性能、资源管理和可伸缩性优势。 - 如何在多核处理器上优化多线程应用程序?
可以调整线程池大小,以利用处理器的内核数量。还需要小心管理线程同步,以避免性能瓶颈。