多线程应用程序在JUnit Test之后不会运行

时间:2018-03-14 18:44:19

标签: java multithreading intellij-idea junit

我的打印机 - 学校问题出了问题。它应该是一个多线程应用程序,到目前为止运行正常。但是当我第二次或第三次运行它时它不再工作..没有错误信息。看起来像线程睡不着左右。此外,当我使用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;
}
}

希望有人能发现我犯的错误:(

非常感谢!!!

2 个答案:

答案 0 :(得分:1)

问题是你混淆了两种状态:

  • 目前有可用的值
  • 将不再有值

向Storage类添加hasEnded()方法,检查是否已达到最终值。确保同步此方法以及hasValue()方法。需要对读写访问进行同步!

然后在循环检查时Printer进行hasEnded,而不是hasValue

最后:摆脱所有sleep()来电。

你自己的答案,解决睡眠问题,并不是一个真正的解决方案。线程安全程序不依赖于计算机的性能来正常运行。

答案 1 :(得分:0)

    z.start();
    z.sleep(100);
    d.start();

在开始拖曳螺纹之间延迟解决了我的问题。我的电脑在开始使用Thread d之前在Thread z中的速度可能太快了。这就是为什么它会在50%的时间里自行解决。

感谢所有人:)