首页 >Java >java教程 >多线程概念部分饥饿

多线程概念部分饥饿

Linda Hamilton
Linda Hamilton原创
2024-10-22 06:09:03822浏览

欢迎来到我们的多线程系列的第 2 部分!在第 1 部分中,我们探讨了原子性不变性

在这一部分中,我们将深入了解饥饿,因为它对于工程师来说至关重要,因为它确保了公平性和系统性能。通过认识饥饿风险,工程师可以设计优先考虑公平性、防止资源垄断并确保所有线程获得必要的 CPU 时间和资源以实现最佳运行的系统。

游戏大厅中永无休止的等待

想象一下您正在玩在线多人游戏,并且您正在尝试加入流行游戏模式的大厅,例如团队战斗。你已经在大厅等待了一段时间,但每次比赛开始时,一批网速更快或技能排名更高的新玩家都会优先添加到游戏中。你看到比赛一遍又一遍地开始,但你似乎从来没有进去过!

从技术上讲,您已经在队列中,但由于响应时间更快或排名更高的其他玩家不断先进入游戏,因此您会无限期地留在大厅中。尽管拥有功能完美的系统,但由于匹配算法不公平地优先考虑其他人,您被剥夺了玩游戏的机会。

Multithreading Concepts Part  Starvation

1. 饥饿

饥饿是指进程不断被拒绝访问其继续运行所需的资源,即使这些资源可用。该进程保持等待状态,因为较高优先级的进程或其他资源分配策略阻止它获取必要的资源。与死锁不同,资源并不是完全不可用,而是进程由于调度不公平而无法访问它们。

2. 原因

  • 优先级反转:当较高优先级进程正在等待较低优先级进程所持有的资源时,如果其他较高优先级进程正在等待较低优先级进程的 CPU 时间,则较低优先级进程可能会缺乏 CPU 时间。进程不断到达。

  • 资源分配策略:某些调度算法可能会偏向某些进程(通常是优先级较高的进程),导致优先级较低的进程很少被分配资源。

  • 设计不佳的算法:如果资源分配算法不平衡或不公平,可能会导致某些流程不断被忽视。

  • 高资源需求:如果少数进程需要过多的资源,它们可能会通过独占这些资源而导致其他进程挨饿。

  • 等待时间长:经常被抢占或发现自己在竞争有限资源的进程可能会遇到饥饿。

3. 防止饥饿

  • 公平地使用 ReentrantLock

Java 的 ReentrantLock 提供了一个强制公平的选项。通过使用带有 true 参数的 ReentrantLock 构造函数,我们可以确保线程以先来先服务 (FCFS) 的方式获取锁,从而防止饥饿。

private final Lock lock = new ReentrantLock(true); // Fair lock
  • 使用信号量实现公平资源共享

信号量用于控制对有限数量资源的访问。通过使用启用公平性的信号量,我们可以确保线程以公平的顺序获取许可,避免饥饿。

private final Semaphore sp = new Semaphore(1, true); // Fair semaphore

Semaphore(1, true) 是一种只有一个许可且启用公平性的信号量。

  • 避免生产者-消费者问题中的饥饿(使用 BlockingQueue)

在传统的生产者-消费者问题中,如果生产者压倒消费者或者消费者被拒绝访问共享资源,则可能会发生饥饿。 BlockingQueue 可以防止这种情况发生,因为它会自动处理生产者和消费者之间的同步。当队列已满或为空时,生产者和消费者分别被阻塞。这确保了两者之间的公平平衡,并防止其中一个压倒另一个,从而避免饥饿。

  • 使用Java的ForkJoinPool进行公平任务调度

在多个任务被 fork 和 join 的场景中,Java 中的 ForkJoinPool 提供了一种在线程之间公平地平衡工作的方法。它确保工作窃取,防止活动较少的线程出现饥饿现象。 Java 的 ForkJoinPool 可以有效地处理任务分割和平衡,确保没有线程因工作而饿死。这是通过使用工作窃取算法来实现的,其中空闲线程从繁忙线程中窃取任务,以保持一切顺利进行

4. 操作系统如何防止饥饿

操作系统 (OS) 使用各种技术来避免饥饿,即由于较高优先级的任务占据主导地位,某些进程或线程长时间无法获得必要的资源(例如 CPU 时间、内存或 I/O 访问)的情况。以下是操作系统防止饥饿的一些常见方法:

No. Method Description Prevents Starvation By
1 Aging Gradually increases priority of waiting processes. Prevents long waits by adjusting priority based on wait time.
2 Round-Robin Scheduling Allocates CPU time in a fixed cyclic order. Ensures all processes get CPU time, avoiding starvation.
3 Completely Fair Scheduler Allocates CPU based on fairness, independent of priority. Ensures fair distribution of CPU time.
4 Priority Boosting Temporarily raises the priority of starved processes holding important resources. Prevents priority inversion and ensures high-priority tasks get needed resources.
5 Multilevel Feedback Queues Dynamically adjusts process priorities based on behavior. Promotes long-waiting processes to higher-priority queues.
6 Semaphores with Fairness Ensures fair access to resources through FIFO queues. Prevents low-priority tasks from being perpetually blocked by higher-priority tasks.
7 Fair Resource Allocation Distributes system resources like CPU and memory based on process demand and need. Prevents resource-hogging processes from starving others.
8 Fair I/O Scheduling Prioritizes I/O requests to ensure timely completion for all processes. Prevents disk I/O starvation for processes making low-priority requests.

通过实施这些策略,操作系统可以确保没有进程或线程无限期地缺乏资源,从而促进更公平、更高效地使用系统资源。

软件工程师的要点

  • 饥饿是一个进度问题,其中进程不断被拒绝访问资源,但不一定涉及其他进程在死锁循环中阻塞它。往往是由于调度或资源分配不公平造成的。
  • 饥饿即使它需要的资源可用,也会发生,但它永远没有机会获取它。
  • 即使系统没有死锁,饥饿也会发生。
  • 饥饿可能是死锁预防的副作用(例如,优先考虑某些进程以避免死锁),因此平衡公平性与避免死锁策略至关重要。

参考

非常感谢在线文档、社区和所有可用资源,使本文成为可能。

  1. 多线程概念第 1 部分:原子性和不变性
  2. Stackoverflow
  3. 信息图形

以上是多线程概念部分饥饿的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn