Wer kann mir die Ausgabe beim auführen der CounterTests sagen?

Gegeben ist folgende Klasse Counter für Aufzählungszwecke:


Java:
public class Counter {
private long counter = 0l;
public long getCounter() {
return counter;
}
void setCounter(long counter) {
this.counter = counter;
}
public void count() {
long c = counter;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.counter = c + 1l;
}
}


Zusätzlich ist folgende Runnable-Implementierung gegeben:


Java:
public class CounterRunnable implements Runnable {
private Counter counter;
public CounterRunnable(Counter counter) {
super();
this.counter = counter;
}
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
counter.count();
}
}
}


Nun wird folgender JUnit-Test ausgeführt:
Java:
public class CounterTest {
@Test
public void testCount() {
Counter c = new Counter();
for (int i = 1; i <= 50; i++) c.count();
for (int i = 1; i <= 50; i++) c.count();
assertEquals(100l, c.getCounter());
}
@Test
public void testCount2() {
Counter c = new Counter();
Thread t1 = new Thread(new CounterRunnable(c));
Thread t2 = new Thread(new CounterRunnable(c));
t1.run();
t2.run();
assertEquals(100l, c.getCounter());
}
@Test
public void testCount3() throws InterruptedException {
Counter c = new Counter();
Thread t1 = new Thread(new CounterRunnable(c));
Thread t2 = new Thread(new CounterRunnable(c));
t1.start();
t2.start();
Thread.sleep(2000);
assertEquals(100l, c.getCounter());
}
}
Was sind die Ergebnisse der einzelnen Test-Methoden und warum?
 
Zuletzt bearbeitet von einem Moderator:

Joose

Top Contributor
Wo liegt das Problem beim Selber ausführen? Der Code existiert ja schon, sollte also kein Problem sein den per Copy&Paste in einen Editor/IDE einzutragen
 

Dompteur

Top Contributor
Beim ersten Test wird die count Methode hintereinander aufgerufen. Daher kommt beim Test das erwartete Ergebnis raus.

Bei den beiden anderen Tests hast du 2 parallel laufende Threads, die das gleiche Objekt verändern. Das heißt im konkreten Fall merkst du dir im Thread 1 den counter Wert in einer Variablen c und wartest 10 mSek. Danach weißt du dem Counter c + 11 zu. In der gleichen Zeit könnte der anderer Thread den Counter ebenfalls bereits verändert haben. Dann überschreibst du dessen Änderung.

Zusätzlich fällt mir bei Test 2 auf, dass die beiden neu gestarteten Threads ja noch laufen, wenn du den Counter-Wert testest. Bei Test 3 ist das nicht so. Da wartest du ja 2 Sekunden bevor du den Counterstand prüfst.
 
Ausgabe Test1 ist ja Zahlen 1 bis 50 nacheinander.

Ausgabe Test2 ist auch Zahlen 1 bis 50 nacheinander.

Und bei Test 3 Zahlen 1 bis 50 aber doppelt. also z.b. 1 1-> 2 2-> 3 3 usw...

Wie kann ich den dritten verändern das er auch einfach die Ausgabe macht?
 

Dompteur

Top Contributor
In der ursprünglichen Fassung des Beispielcodes gibt es ja keine Ausgabe.
Du kannst aber in der Counter.count() Methode eine Ausgabeanweisung hinzufügen. Wenn du den Counter ausgibst, dann wirst du sehen, wie der Counter in 11-er Schritten hochgezählt wird.

Bei Test 2 und 3 wirst du dann sehen, dass ab und zu eine Zahl doppelt hintereinander ausgegeben wird.

Eine gute Einführung in die Programmierung von parallel ablaufenden Threads findest du hier Rheinwerk Computing :: Java ist auch eine Insel - 12 Einführung in die nebenläufige Programmierung

Besonders das Kapitel über Synchronisieren Rheinwerk Computing :: Java ist auch eine Insel - 12 Einführung in die nebenläufige Programmierung solltest du dir genauer anschauen.
 

Neue Themen


Oben