tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von Fabio Hellmann
ERLEDIGT
JA
ANTWORTEN
13
ZUGRIFFE
632
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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!
     

  2. #2
    genodeftest genodeftest ist offline Mitglied Brillant
    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)
    Code java:
    1
    
    System.out.println("Hallo");
    hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.
    ___________
    Ubuntu Bug #1: Microsoft has a majority market share
    Casecon: Projekt leiser Käse

  3. #3
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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?
     

  4. #4
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    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ß

    Fabio
     
    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.

  5. #5
    genodeftest genodeftest ist offline Mitglied Brillant
    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)
    Code java:
    1
    
    System.out.println("Hallo");
    hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.
    ___________
    Ubuntu Bug #1: Microsoft has a majority market share
    Casecon: Projekt leiser Käse

  6. #6
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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 )
     

  7. #7
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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

    Code java:
    1
    
    pt.start();
    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?

    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?
     

  8. #8
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    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.

  9. #9
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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
     

  10. #10
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    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.

  11. #11
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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
     

  12. #12
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    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ß

    Fabio
    Miaming bedankt sich. 
    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.

  13. #13
    Miaming Miaming ist offline Mitglied Bronze
    Registriert seit
    May 2011
    Beiträge
    40
    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!
     

  14. #14
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    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

  1. List von mehreren Threads abarbeiten lassen
    Von stevetc im Forum Algorithmen & Datenstrukturen mit Java
    Antworten: 0
    Letzter Beitrag: 30.09.09, 15:06
  2. Thread abarbeiten
    Von anjepieft im Forum Java Grundlagen
    Antworten: 7
    Letzter Beitrag: 29.05.08, 14:44
  3. Antworten: 6
    Letzter Beitrag: 24.11.05, 13:56
  4. Formulareingaben abarbeiten
    Von nemo1980 im Forum PHP
    Antworten: 1
    Letzter Beitrag: 04.04.05, 10:07
  5. schneller scripts abarbeiten?
    Von shiver im Forum PHP
    Antworten: 5
    Letzter Beitrag: 03.08.01, 17:49