我正在启动两个线程 T1 打印 1,3,5,..... 和线程两个 T2 打印 2,4,6.... 下面是执行此操作的代码。
public class T1T2Print {
public static void main(String[] args) {
Counter c = new Counter();
c.count = 1;
printThread t1 = new printThread(c);
Thread T1 = new Thread(t1);
T1.setName("T1");
printThread t2 = new printThread(c);
Thread T2 = new Thread(t2);
T2.setName("T2");
T2.start();
T1.start();
}
}
class printThread implements Runnable {
public Counter count;
public int reminder;
public printThread(Counter count) {
this.count = count;
}
public void run() {
for (int i = 1; i <= 5; i++) {
synchronized (count) {
String name = Thread.currentThread().getName();
if (count.count % 2 != 0 && !name.equals("T1")) {
try {
count.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(name + " :: " + count.count);
count.count++;
count.notify();
}
if (count.count % 2 == 0 && !name.equals("T2")) {
try {
count.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(name + " :: " + count.count);
count.count++;
count.notify();
}
}
}
}
}
输出如下:
T1 :: 1
T2 :: 2
T1 :: 3
T2 :: 4
T1 :: 5
T2 :: 6
T1 :: 7
T2 :: 8
T1 :: 9
T2 :: 10
但是当我将启动线程的顺序更改为
T1.start();
T2.start();
输出变化如下,为什么会这样
T1 :: 1
T2 :: 2
T2 :: 3
T2 :: 4
T2 :: 5
T2 :: 6
T2 :: 7
T2 :: 8
T2 :: 9
T2 :: 10
T2 :: 11
T1 :: 12
T1 :: 13
T1 :: 14
T1 :: 15
T1 :: 16
T1 :: 17
T1 :: 18
T1 :: 19
最佳答案
让我们在 count.wait()
调用之前添加 System.out.println(name + "::waits");
。
然后是第一个案例日志:
T2 :: waits
T1 :: 1
T1 :: waits
T2 :: 2
T2 :: waits
T1 :: 3
T1 :: waits
T2 :: 4
T2 :: waits
T1 :: 5
T1 :: waits
T2 :: 6
T2 :: waits
T1 :: 7
T1 :: waits
T2 :: 8
T2 :: waits
T1 :: 9
T1 :: waits
T2 :: 10
案例二:
T1 :: 1
T1 :: waits
T2 :: 2
T2 :: 3
T1 :: 4
T1 :: 5
T1 :: 6
T1 :: 7
T1 :: 8
T1 :: 9
T1 :: 10
T1 :: 11
T2 :: 12
T2 :: 13
T2 :: 14
T2 :: 15
T2 :: 16
T2 :: 17
T2 :: 18
正如您在第二种情况中看到的那样,线程不会 hibernate 。为什么?因为在第二种情况下,每个线程增加计数器两次(第一个 if
一次,第二个 if
一次)(并在同步中执行方式)。 (我可以假设你不想要这个逻辑,这是你犯的错误)。这两种情况有什么区别?在第一种情况下 T2
更早开始并在第一个中等待,如果在收到通知后它醒来并转到第二个如果,即它每次迭代仅增加(并打印)计数器一次.这就是为什么。
关于java - 线程执行不可预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39848750/