1Danke
ERLEDIGT
JA
JA
ANTWORTEN
13
13
ZUGRIFFE
632
632
EMPFEHLEN
-
Hallo zusammen, mal wieder eine Frage diesmal bezogen auf das Thema Threads - Die Aufgabe:
class Lager {
private int bestand;
private static final int kapazität = 20;
public void einlagern() {
if (bestand+5 <= kapazität) {
bestand+=5;
System.out.println("nach einlagern :" + bestand);
}
}
public void entnehmen() {
if (bestand-3 >= 0) {
bestand-=3;
System.out.println("nach entnehmen :" + bestand);
}
}
}
Ein Produzenten-Thread-Objekt versucht in einer Endlosschleife jeweils Waren einzulagern,
wie der folgende Java-Quelltext zeigt:
class ProduzentThread extends Thread {
private Lager lager;
ProduzentThread(Lager lager) {
this.lager = lager;
}
public void run() {
while(true){
lager.einlagern();
}
}
}
Analog dazu versucht ein Konsumenten-Thread-Objekt in einer Endlosschleife jeweils Waren
aus dem Lagerbestand zu entnehmen. Der Quelltext ist analog zum Produzenten gestaltet. In
der while-Schleife wird hier die Methode lager.entnehmen() aufgerufen.
In ihrer Main-Methode wird jeweils ein Objekt der Klasse Lager, ProduzentThread und
KonsumentThread angelegt (vgl. Skizze). Anschließend wird erst pt.start() und
dann kt.start() aufgerufen.
Die Ausgabe:
Code java:1 2 3 4 5 6 7 8 9 10
Eine Ausführung der Anwendung führt zu folgender Ausgabe: ........... nach entnehmen : 1 nach einlagern : 6 nach einlagern : 8 nach einlagern : 13 nach einlagern : 18 nach entnehmen : 3 nach entnehmen : 15 nach entnehmen : 12
Das allgemeine Grundproblem welches ich habe, ist die Tatsache dass ich schon nicht weiß, wie die erste Ausgabe überhaupt zu Stande kommt.
Könnte mir jemand irgendwie nen bisschen erklären, wie das Programm arbeitet? Nach welchen Schritten? Also es scheint so als würde ich den Zusammenhang zwischen Threads und dem Programm nicht im Ansatz verstehen, deshalb hoffe ich darauf dass mir es jemand anfängerfreundlich erklären könnte
Ich bedanke mich voraus!
-
29.12.11 22:46 #2
- Registriert seit
- Jun 2009
- Beiträge
- 870
Welche IDE benutzt du? Probier doch mal den Debugger aus, bei Eclipse siehe http://www.youtube.com/results?searc...&search=Search
Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
-
danke für den tipp!
setzte ich den haltepunkt dort, wo ich den wert wissen möchte? also bei "int bestand" ? in meiner lager klasse?
-
29.12.11 23:24 #4
Hi,
die Ausgabe die du bei diesem Programm erhälst wird zu 99,99% in aller Fälle immer unterschiedlich sein. Das liegt daran, dass die 2 Threads (ProduzentThread und KonsumentThread) unterschiedlich vom Betriebssystem-Scheduler bearbeitet werden.
Da in der Aufgabenstellung steht, dass der ProduzentThread vor dem KonsumentThread gestartet wird, wird der Scheduler zu erst diesen Thread arbeiten lassen. Je nach Hardwarevoraussetzungen und Scheduler läuft dieser Thread dann eine bestimmte Zeit, bevor der KonsumentThread bearbeitet wird.
Desweitern musst du beachten, dass die Methoden einlagern() und entnehmen() bzw die Variable bestand nicht syncronized ist, was bedeutet, dass auf diese Variable von mehreren Threads "gleichzeitig" zugegriffen werden kann und dadurch eine inkonsistenz im Programmablauf entstehen kann.
Genau aus diesem Grund vermute ich mal, dass bei deiner Ausgabe als erstes eine 1 steht. Ich würde mir das folgendermaßen erklären:
ProduzentThread ruft die Methode einlagern auf, wobei auf die Variable bestand in byte-Ebene die 5 Einheiten dazugerechnet werden. Während der ProduzentThread eben diese 5 Einheiten draufrechnet, fragt der KonsumentThread mit der Methode entehmen die Variable bestand ab und rechnet -3 wieder auf byte-Ebene, obwohl der andere Thread noch am summieren ist.
Um das ganze mal ein wenig zu veranschaulichen:
Scheduler bearbeitet 1 Thread...
ProduzentThread: einlagern()
bestand = 1
bestand = 2
bestand = 3
bestand = 4
// Hier unterbricht der Scheduler den Thread
Scheduler bearbeitet 2 Thread...
KonsumentThread: entehmen()
bestand = 3
bestand = 2
bestand = 1
System.out.println(bestand) // = 1
Scheduler bearbeitet 1 Thread...
ProduzentThread: einlagern()
... und so weiter....
Oder deine Variable bestand startet nicht bei dem Wert 0 sondern bei -1, wobei mich das doch sehr täuschen würde.
Ich würde dir mal empfehlen vor die If-Bedingung von beiden Methoden eine Ausgabe einzubinden, damit du vor der Berechnung siehst, welcher Thread gerade arbeitet.
Gruß
FabioBitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
-
29.12.11 23:29 #5
- Registriert seit
- Jun 2009
- Beiträge
- 870
zum debugger: mit rechte Maustaste | toggle Breakpoint setzt du einen Haltepunkt nach der Ausführung von dem Inhalt der aktuellen Zeile.
Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
-
Hallo Fabio, deine Erklärung scheint mir als sehr einleuchtend und verständlich! Vielen für die Antwort! Ich glaube ich habe den Vorgang / die Abarbeitung der Threads anhand des Beispiels besser verstanden!
@genodeftest: Das mit dem Debugger hat nur bedingt funktioniert :S Ich hab die jeweiligen Klassen und Methoden erstellt.
Habe dann nach der Zeile private int bestand den breakpoints gesetzt und den Debugger ausgeführt (von der klasse test - da wo die main steht) allerdings beginnt dann schon die endlosschleife zu laufen - benötige ich einen weiteren Breakpoint? (sorry is vielleicht doof de frage allerdings bin ich mit dem ganzen nicht so vertraut )
-
sorry für den doppelpost aber ich habe doch noch eine frage dazu an dich fabio:
und zwar hast du geschrieben, dasss der produzententhread zuerst gestartet wird, was ja auch der aufgabenstellung entspricht! erst wird der produzententhread gestartet
im Anschluß erfolgt die Ausführung des Konsumententhreads! (nach entnehmen: 20, nach entnehmen 17... ) Allerdings frage ich mich dann, warum als erstes die Ausgabe des Konsumententhreads erfolgt?Code java:1
pt.start();
Du hast recht, die Ausgaben erscheinen randommäßig gestern erhielt ich andere Ausgaben als heute allerdings bekomme ich immer zuerst die Ausgabe die Ausgabe "nach entnehmen" obwohl diese Methode im Konsumententhread bearbeitet wird - allerdings wird der Thread ja später gestartet wieso kommt es dann zu dieser Ausgabe? also warum erfolgt ich als erstes die Ausgabe des Produzententhreads, wenn dieser ja als erstes gestartet wird?
-
30.12.11 14:14 #8
Wenn man mit Threads arbeitet kann man sich nie zu 100% auf die Konsole verlassen, da die Ausgabe immer Zeitversetzt zur eigentlich Ausführung kommt.
Allerdings kann ich mir nicht vorstellen, dass die Variable bereits auf 20 gesetzt wurde, ohne eine Ausgabe vorher gemacht zu haben. Kann es evtl. sein, dass die Konsole nach unten gescrollt hat und du nur den unteren Teil gelesen hast?Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
-
Danke der Beitrag wurde von einem Admin wohl gelöscht, weil ich eine zulange Ausgabe gepostet habe: Ich poste nun hier mal eine kürzere Ausgabe die ich erhalte wenn ich das Programm ausführe:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
nach einlagern :20 nach entnehmen :20 nach entnehmen :17 nach entnehmen :19 nach entnehmen :16 nach entnehmen :13 nach entnehmen :10 nach entnehmen :7 nach entnehmen :4 nach entnehmen :1 nach einlagern :19 nach einlagern :6 nach einlagern :8 nach einlagern :13 nach einlagern :18 nach entnehmen :3 nach einlagern :20 nach entnehmen :20
gestern erhielt ich widerum ne komplett andere ausgabe.... und es wurde auch nicht mit der methode "nach einlagern" aus dem Produzententhread gestartet, sondern mit der Methode "nach entnehmen" aus dem Konsumententhread ... issn bisschen mysteriös das ganze... auf wunsch poste ich gerne dazu den vollständigen quelltext den ich aus der vorgegeben aufgabenstellung gebastelt habe
frohes neues an alle btw
-
01.01.12 19:49 #10
Hi und auch dir ein frohes Neues,
vielleicht könntest du uns mal genau sagen, was du bei dieser Aufgabe nicht verstehst. Bzw. was du in dieser Aufgabe machen musst, wo du nicht weiter kommst.Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
-
Guten Morgen,
das eigentliche Grundproblem bei der Aufgabe ist es, versuchen zu erklären, wie die Ausgabe zu Stande kommt. Und im Normalfall geht man davon aus, dass eine gewisse "Logik" dahinter steckt. Nach merhmaligen Testen komm ich zu dem Entschluss, dass es zwar eine gewisse Grundlogik gibt, diese jedoch nicht allgemein anwendbar ist, da es sich um Threads handelt und es aufgrund der fehlenden Synchronisation zu Zugriffskoordination kommt.
Ich könnte zu keinem Zeitpunkt bestimmen, wann der Wert "bestand" welchen Wert annimmt, und genau diese Tatsache macht mich ratlos, da ich bezweifel dass wenn ich eine solche Aufgabe in der Klausur lösen müsste die Begründung die ich hier schreibe richtig ist?
Also Sinn und Zweck ist es versuchen die obige Ausgabe (erster Post) zu erklären. Ich mein alles würde anders aussehen wenn es hier nur ein Thread geben würde, denn dann würde ich die Abarbeitung des Programms ganz normal erklären können, da hier zwei Thread zeitlich auf eine Resource zugreifen (bestand) kommt es zu Problemen und joa ich bin quasi auf der Suche nach einer korrekten fachlichen Begründung / Erklärung des Programms
-
02.01.12 18:13 #12
Je nachdem wie tief ihr in dieses Thema eingestiegen seit, kannst du eine von den von mir bereits genannten Antworten liefern.
1. Bei oberflächlicher Bearbeitung des Themas:
- Die nicht vorhandene Syncronization.
2. Bei tiefergehenden Bearbeitungen des Themas:
- Die Bearbeitung der Threads durch den Scheduler.
- und 1.
Gruß
FabioBitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
-
alles klar werde es mir zu herzen nehmen und im falle einer möglichen frage in der bevorstehenden klausur werd ich deine begründung nehmen - so in der art stand es auch inna vorlesung drin ... also stichpunkt synchronisation und bedingte synchronisation - probleme der zugriffskoordination bei gleichzeitiger nutzung der resource (hier int bestand) von daher denke ich dass sich dann 1. wohl am besten anbietet - vielen dank fabio dass du dich bisher so bemüht hast mir zu helfen - hilft mir für meine vorbereitung wirklich sehr weiter - dankeschön dafür!
-
02.01.12 22:27 #14
Keine Ursache. Freut mich wenn ich helfen konnte.

Wenn das Thema dann geklärt ist, wäre es super, wenn du es noch als erledigt markieren würdest.
Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
Ähnliche Themen
-
List von mehreren Threads abarbeiten lassen
Von stevetc im Forum Algorithmen & Datenstrukturen mit JavaAntworten: 0Letzter Beitrag: 30.09.09, 15:06 -
Thread abarbeiten
Von anjepieft im Forum Java GrundlagenAntworten: 7Letzter Beitrag: 29.05.08, 14:44 -
Threads: WaitForMultipleObjects(); wartet nicht wenn ich über 64 Threads starte
Von FBIagent im Forum C/C++Antworten: 6Letzter Beitrag: 24.11.05, 13:56 -
Formulareingaben abarbeiten
Von nemo1980 im Forum PHPAntworten: 1Letzter Beitrag: 04.04.05, 10:07 -
schneller scripts abarbeiten?
Von shiver im Forum PHPAntworten: 5Letzter Beitrag: 03.08.01, 17:49





Zitieren
Login





