java - 线程没有被终止;陷入循环
问题描述
我有 4 个线程,每个线程都在执行不同的方法,我能够提取所需的输出,但是当作业完成时线程没有被终止或无法退出循环。
有人可以帮我谈谈你的意见。
我认为每个线程都坚持等待声明并期待有人发出信号。我尝试在任务完成后明确地向所有线程发出信号,但没有运气。
当一个线程向其他线程发出信号时,执行线程不会重新检查 while 循环的条件,因为我将标志设置为 false 但它没有任何效果。
private int n;
Lock lock = new ReentrantLock();
Condition executeFizz;
Condition executeBuzz;
Condition executeFizzBuzz;
Condition executeNumber;
volatile private boolean flag;
public FizzyBuzz(int n) {
this.n = n;
this.executeFizz = lock.newCondition();
this.executeBuzz = lock.newCondition();
this.executeFizzBuzz = lock.newCondition();
this.executeNumber = lock.newCondition();
this.flag = true;
}
public void fizz() {
lock.lock();
while(true) {
try {
executeFizz.await();
if(!flag) break;
} catch (InterruptedException e) {
}
System.out.println("fizz");
executeNumber.signal();
}
}
public void buzz() {
lock.lock();
while(true) {
try {
executeBuzz.await();
if(!flag) break;
} catch (InterruptedException e) {
}
System.out.println("buzz");
executeNumber.signal();
}
}
public void fizzbuzz() {
lock.lock();
while(true) {
try {
executeFizzBuzz.await();
if(!flag) break;
} catch (InterruptedException e) {
}
System.out.println("fizzbuzz");
executeNumber.signal();
}
}
public void number() throws InterruptedException {
lock.lock();
for(int i=1;i<=n;i++)
{
if(i%3==0&&i%5==0)
{
executeFizzBuzz.signal();
executeNumber.await();
}
else if(i%3==0)
{
executeFizz.signal();
executeNumber.await();
}
else if(i%5==0)
{
executeBuzz.signal();
executeNumber.await();
}
else
{
System.out.println(i);
}
}
flag = false;
executeFizzBuzz.signal();
executeFizz.signal();
executeBuzz.signal();
解决方案
也许这不会像你想象的那样做:
while (flag) {
...
}
每当变为假时,该循环都不会终止。flag
它在测试 flag
并发现它是错误的时终止。每次在循环中只发生一次。您可以改为这样编写循环,它的行为方式完全相同:
while (true) {
if (! flag) break;
...
}
所以如果你有这个,
while (flag) {
...executeFizz.await()...
}
如果flag
线程卡在调用中时从 true 更改为 false await()
,则循环不会终止,直到调用返回await()
......
...这在您的示例中永远不会发生,因为在for
循环计数到之后n
,它会设置flag=false;
但它不会向任何其他等待线程发出信号。
@SolomonSlow 我尝试向所有 3 个信号发送信号,但在添加 if 条件后没有运气,在代码的末尾我包含了此代码...
我的猜测是,这是因为您的程序中没有调用lock.unlock()
任何地方。以下是可能发生的情况:
三个“工作”线程都在调用
executeXxxxx.await()
(每个都在等待自己的条件变量。)“主”线程到达循环的末尾(它当前是 , 的所有者
lock
),它向每个executeXxxxxx
条件变量发出信号。“主”线程结束,但
lock
仍被锁定。现在,所有三个“工作”线程都已从等待各自条件的状态中释放出来,但await()
在锁可用之前,它们的调用无法返回。锁永远不会可用,因为没有运行线程可以解锁它。
您需要在每个线程lock.unlock()
结束之前调用它。
推荐阅读
- android - 使用间谍与无间谍的 Mockito 性能
- ruby-on-rails - 测试路由器在两个具有相同名称的控制器中混淆
- c++ - 为什么 C++ 类函数没有 low_pc / high_pc DWARF 信息
- php - Laravel 雄辩的搜索/过滤
- python - 从嵌套字典中获取此值的更简洁方法?
- acumatica - 尝试创建新行时获取重复的 Cache.Inserted 记录
- sql - 在 Spark 上更新 Oracle 表时如何避免 ORA-00060(检测到死锁)错误
- java - 在命令行上转义 Maven 属性
- react-native - 用玩笑测试 expo 应用程序,但由于实验性语法测试崩溃
- javascript - SyntaxError:Node.js 中 Module._compile 的输入意外结束