【发布时间】:2019-10-11 00:40:14
【问题描述】:
我正在解决一个小问题,我需要使用两个线程以交替方式顺序打印数字。就像线程 1 打印 1,线程 2 打印 2,线程 1 打印 3 等等......
所以我在下面创建了一段代码,但在某些时候,两个线程都进入了等待状态,控制台上什么也没有打印出来。
import java.util.concurrent.atomic.AtomicInteger;
public class MultiPrintSequence {
public static void main(String[] args) {
AtomicInteger integer=new AtomicInteger(0);
Sequence sequence1=new Sequence(integer);
Sequence sequence2=new Sequence(integer);
sequence1.start();
sequence2.start();
}
}
class Sequence extends Thread{
private AtomicInteger integer;
boolean flag=false;
public Sequence(AtomicInteger integer) {
this.integer=integer;
}
@Override
public void run() {
while(true) {
synchronized (integer) {
while (flag) {
flag=false;
try {
System.out.println(Thread.currentThread().getName()+" waiting");
integer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" "+integer.incrementAndGet());
flag = true;
System.out.println(Thread.currentThread().getName()+" notifying");
integer.notify();
}
}
}
}
在观察控制台输出时,我注意到在某个时候,当一个线程发出通知时,另一个线程最终甚至在通知线程进入等待状态之前就启动了,因此在某一时刻,两个线程都进入了等待状态。下面是控制台输出的一小部分。
Thread-1 510
Thread-1 notifying
Thread-1 waiting
Thread-0 511
Thread-0 notifying
Thread-0 waiting
Thread-1 512
Thread-1 notifying
Thread-1 waiting
**Thread-0 513
Thread-0 notifying
Thread-1 514
Thread-1 notifying
Thread-1 waiting
Thread-0 waiting**
【问题讨论】:
-
共享可变状态,这就是问题所在。你有很好的意识来正确地共享整数,但不是为了标志。
-
实际上我刚刚遇到了问题,是的,我们可以使标志在两个线程之间共享。但这并不是真正的问题。我的 while 块结构很差。 while(true) 块应该在同步块内,并用 if 替换 while(flag) ,我们就完成了。这是一次严重的失误。但是,代码也适用于您的解决方案,谢谢 :)
-
IMO,您需要更加仔细地思考
flag的含义。您的两个线程都执行相同的代码,并且它们都被赋予相同的参数。它们是相同的。但他们应该是不同的。其中一个应该只打印奇数,另一个应该只打印偶数。您需要一种方法来告诉线程,“您的工作是只打印偶数”(或“奇数”);并且您需要一种方法让每个线程等到打印偶数/奇数的时间。 -
P.S.,为了额外的功劳,找出为什么这个问题与线程旨在解决的问题几乎完全相反。 (提示,与线程有关的一切都与“并发”这个词有关。)
标签: java multithreading java-threads