gpt4 book ai didi

java - 在我的程序中线程没有按顺序打印

转载 作者:行者123 更新时间:2023-11-29 04:08:45 26 4
gpt4 key购买 nike

我有下面的程序来对 3 个线程进行排序。例如,首先应该打印第一个线程,然后是第二个线程,然后是第三个线程。但下面的程序实际上并没有这样做,也没有打印一些随机序列。我在 stackoverflow 本身上看到了一些程序,它们执行并尝试按顺序打印。

但我真的很努力去理解为什么下面的程序不工作以及我无法理解的是什么。

package my.tutorial.java;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class SequenceThreads {
private static final Object lock = new Object();

static class Task implements Runnable {
private final String tName;
private final int turnId;
private static int nextTurn = 1;

public Task(String tName, int turnId) {
this.tName = tName;
this.turnId = turnId;
}

@Override
public void run() {
while (true) {
synchronized (lock) {
if (nextTurn != turnId) {
try {
// System.out.println(tName + " went waiting " + nCount);
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

// System.out.println(tName + " went waiting");
System.out.println(tName + " Executed ");
++nextTurn;
if (nextTurn == 4)
nextTurn = 1;

// System.out.println(nextTurn);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify();
}


}
}
}

public static void main(String[] args) throws InterruptedException {
final Executor executor = Executors.newFixedThreadPool(3);
//AtomicInteger nCount = new AtomicInteger(1);
final Task task1 = new Task("T1", 1);
final Task task2 = new Task("T2", 2);
final Task task3 = new Task("T3", 3);
executor.execute(task1);
executor.execute(task2);
executor.execute(task3);
}
}

预期的结果应该是

T1 Executed
T2 Executed
T3 Executed
T1 Executed
T2 Executed
T3 Executed

但实际结果是

T1 Executed  
T2 Executed
T1 Executed
T1 Executed
T3 Executed
T3 Executed
T1 Executed
T3 Executed
T3 Executed

最佳答案

您的代码有 2 个问题。

1.) 您使用 if 语句中的 nextTurn != turnId 检查是否轮到线程打印。这意味着如果一个线程到达这个if,就轮不到线程了,它等待一次,然后可以再次被唤醒,它可能仍然轮不到那个线程,但它不会再次检查,只是继续乱序执行。

要解决这个问题,请将此 if 转换为 while

2.) notify() 不会唤醒所有等待的线程。这意味着您可能会遇到错误的线程被唤醒的情况,检查并发现还没有轮到该线程,然后再次进入 hibernate 状态,然后永远不会到达 notify() 调用,所以正确的线程永远不会被唤醒。在那种情况下,我们将解除锁定,除非发生虚假唤醒。

为此,您可以改用 notifyAll()

在修复了这两件事后,我看到了预期的输出:

T1 Executed  
T2 Executed
T3 Executed
T1 Executed
T2 Executed
T3 Executed
T1 Executed
T2 Executed
T3 Executed
...

关于java - 在我的程序中线程没有按顺序打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56501323/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com