我的打印机 - 学校问题出了问题。它应该是一个多线程应用程序,到目前为止运行正常。但是当我第二次或第三次运行它时它不再工作..没有错误信息。看起来像线程睡不着左右。此外,当我使用JUnit测试进行测试时,它无法正常工作。但有时它确实......本身已经很奇怪了。
public class CounterPrinter {
public static void main(String[] args) throws InterruptedException {
if (args.length != 2) {
System.out.println("Usage: CounterPrinter <min> <max>");
System.exit(1);
}
Storage s = new Storage();
Printer d = new Printer(s, Integer.parseInt(args[1]));
Counter z = new Counter(s, Integer.parseInt(args[0]), Integer.parseInt(args[1]));
z.start();
d.start();
z.join();
d.join();
Thread.sleep(5000);
}
}
public class Printerextends Thread {
private Storage storage;
private Integer ende;
Printer(Storage s, Integer ende) {
this.storage = s;
this.ende = ende;
}
@Override
public void run() {
while (storage.hasValue()) {
try {
System.out.print(speicher.getValue(ende) + " ");
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Counter extends Thread {
private Storage speicher;
private int max, min;
Counter(Storages, int min, int max) {
this.storage = s;
this.max = max;
this.min = min;
}
@Override
public void run() {
for (int i = min; i <= max; i++) {
try {
storage.setValue(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Storage implements StorageIf {
private Integer wert;
private boolean hasValue = false;
@Override
public synchronized Integer getValue(Integer ende) throws InterruptedException {
if(wert.equals(ende)){
hasValue = false;
return wert;
}else {
while (!hasValue()) {
wait();
}
hasValue = false;
notifyAll();
return wert;
}
}
@Override
public synchronized void setValue(Integer wert) throws InterruptedException {
while (hasValue()){
wait();
}
hasValue = true;
this.wert = wert;
notifyAll();
}
@Override
public boolean hasValue() {
return hasValue;
}
}
希望有人能发现我犯的错误:(
非常感谢!!!
答案 0 :(得分:1)
问题是你混淆了两种状态:
向Storage类添加hasEnded()
方法,检查是否已达到最终值。确保同步此方法以及hasValue()
方法。需要对读写访问进行同步!
然后在循环检查时Printer
进行hasEnded
,而不是hasValue
。
最后:摆脱所有sleep()
来电。
你自己的答案,解决睡眠问题,并不是一个真正的解决方案。线程安全程序不依赖于计算机的性能来正常运行。
答案 1 :(得分:0)
z.start();
z.sleep(100);
d.start();
在开始拖曳螺纹之间延迟解决了我的问题。我的电脑在开始使用Thread d之前在Thread z中的速度可能太快了。这就是为什么它会在50%的时间里自行解决。
感谢所有人:)