线程没有终止;陷入循环
Threads are not getting terminatedl; stuck in loop
我有 4 个线程,每个线程都在执行不同的方法,我能够提取所需的输出,但是线程没有终止或在作业完成后无法退出循环。
谁能帮我看看你的意见。
我认为每个线程都停留在 await 语句上并期待有人发出信号。我尝试在任务完成后显式地向所有线程发出信号,但没有成功。
当一个线程向其他线程发出信号时,执行线程不会重新检查 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()...
}
并且如果线程卡在 await()
调用中时 flag
从 true 变为 false,则循环不会终止,直到 after await()
调用 returns...
...这在您的示例中永远不会发生,因为在 for
循环计数到 n
后,它设置 flag=false;
但它不会 向任何其他等待线程发送信号。
@SolomonSlow i tried signalling all 3, but no luck
after adding if condition, at the end of the code I included this code...
我的猜测是,这是因为您的程序中的任何地方都没有调用 lock.unlock()
。以下是可能发生的情况:
三个 "worker" 线程都在调用 executeXxxxx.await()
(每个都在等待自己的条件变量。)
"main" 线程到达循环的末尾(它当前是 lock
的所有者)并且它向每个 executeXxxxxx
条件发出信号变量。
"main"线程结束,但lock
线程仍处于锁定状态。所有三个 "worker" 线程现在都已从等待它们各自的条件中释放出来,但是它们的 await()
调用不能 return 直到锁变得可用。
锁永远不会可用,因为没有 运行 线程可以解锁它。
您需要在每个线程结束前调用 lock.unlock()
。
我有 4 个线程,每个线程都在执行不同的方法,我能够提取所需的输出,但是线程没有终止或在作业完成后无法退出循环。
谁能帮我看看你的意见。
我认为每个线程都停留在 await 语句上并期待有人发出信号。我尝试在任务完成后显式地向所有线程发出信号,但没有成功。
当一个线程向其他线程发出信号时,执行线程不会重新检查 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()...
}
并且如果线程卡在 await()
调用中时 flag
从 true 变为 false,则循环不会终止,直到 after await()
调用 returns...
...这在您的示例中永远不会发生,因为在 for
循环计数到 n
后,它设置 flag=false;
但它不会 向任何其他等待线程发送信号。
@SolomonSlow i tried signalling all 3, but no luck after adding if condition, at the end of the code I included this code...
我的猜测是,这是因为您的程序中的任何地方都没有调用 lock.unlock()
。以下是可能发生的情况:
三个 "worker" 线程都在调用
executeXxxxx.await()
(每个都在等待自己的条件变量。)"main" 线程到达循环的末尾(它当前是
lock
的所有者)并且它向每个executeXxxxxx
条件发出信号变量。"main"线程结束,但
lock
线程仍处于锁定状态。所有三个 "worker" 线程现在都已从等待它们各自的条件中释放出来,但是它们的await()
调用不能 return 直到锁变得可用。锁永远不会可用,因为没有 运行 线程可以解锁它。
您需要在每个线程结束前调用 lock.unlock()
。