使用 volatile 变量控制多线程交替打印「FooBar」时如何避免死锁?

ID:17252 / 打印

使用 volatile 变量控制多线程交替打印「foobar」时如何避免死锁?

使用两个 volatile 变量控制多线程时死锁问题

题目要求设计一个多线程程序交替打印「foobar」。开发者按照题意使用了两个 volatile 变量控制多线程逻辑,但运行后程序卡死在 while 循环中。

原因分析

使用 volatile 变量确实可以防止指令重排序,但它不能解决线程并发访问同一片段内存区域时可能出现的共享变量竞争问题。while 循环中的 busy-wait 代码导致线程一直占用 cpu 资源,无法释放锁,从而造成死锁。

解决方案

为了解决死锁问题,可以使用 wait() 和 notify()/notifyall() 来实现线程之间的协调,从而避免忙等待。

修改后的代码如下:

class FooBar {     private int n;     private boolean flag = false;      public FooBar(int n) {         this.n = n;     }      public synchronized void foo(Runnable printFoo) throws InterruptedException {         for (int i = 0; i < n; i++) {             while (flag) {                 wait();             }             // printFoo.run() outputs "foo". Do not change or remove this line.             printFoo.run();             flag = true;             notifyAll();         }     }      public synchronized void bar(Runnable printBar) throws InterruptedException {         for (int i = 0; i < n; i++) {             while (!flag) {                 wait();             }             // printBar.run() outputs "bar". Do not change or remove this line.             printBar.run();             flag = false;             notifyAll();         }     } }

在修改后的代码中,使用 synchronized 关键字保证了 foo 和 bar 方法的互斥执行。线程在等待条件满足时调用 wait() 方法来等待,并释放锁,让其他线程有机会执行。当条件满足时,线程会调用 notifyall() 方法来唤醒其他等待的线程,从而避免死锁。

上一篇: 使用 Aspose.Words 将 Docx 转换为 PDF 后标题显示为小方块怎么办?
下一篇: 如何用映射容纳不同类、不同返回值类型的 getter 方法引用?

作者:admin @ 24资源网   2024-11-27

本站所有软件、源码、文章均有网友提供,如有侵权联系308410122@qq.com

与本文相关文章

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。