kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Synchronisierung des Zugriffs auf Methoden durch Threads

  • Teilen sich verschiedene Threads einen Speicherbereich, so muß gewährleistet werden, dass ein Thread diesen nicht ausliest, solange ein anderes darauf schreibt und umgekehrt.
  • Um dieses Problem zu lösen, ist es in Java möglich Methoden mit dem Modifikator "synchronized" zu versehen.
  • Dies sorgt dafür, dass niemals zwei Threads gleichzeitig die betreffende Methode benutzen können.
  • Wird diese Methode beispielsweise benutzt, um einen Meßwert zu speichern oder zu lesen (wählbar z.B. über eine boolsche Variable), so kann so dafür gesorgt werden, dass beides nie zur gleichen Zeit versucht wird.
  • Das folgende Programm weist nach, dass diese Technik funktioniert, jedoch ohne tatsächlich eine Aufgabe in der synchronized Methode zu erledigen.
  • In dem Programm gibt es sowohl eine synchronisierte und eine nicht synchronisierte Methode.
  • Beide liefern eine Konsolenausgabe, wenn sie aufgerufen werden und zeigen auch an, von welchem Objekt.
  • Außerdem zeigen sie an, wenn sie wieder verlassen werden.
public class MeinThread extends Thread
{
    MeinThread(String name)
    {
        setName(name);
    }
    public void run()
    {
        while(true)
        {
            Hauptprogramm.synchron(this,100);
            Hauptprogramm.pausieren(20);
            Hauptprogramm.nicht_synchron(this,20);
            Hauptprogramm.pausieren(50);
            Hauptprogramm.nicht_synchron(this,30);
            Hauptprogramm.pausieren(50);
        }
    }
}

Code 0-1: MeinThread.java - Objekte der obigen Java-Klasse greifen sowohl auf eine synchronisiert und auf eine nicht synchronisierte Methode zu.

public class Hauptprogramm
{
    public static void pausieren(long ms)
    {
        try
        {
            Thread.sleep(ms);
        }
        catch(Exception e)
        {
        }
    }
    public static synchronized void synchron(Thread x,long dauer)
    {
        System.out.println("Thread "+x.getName()+" startet die Methode synchron().");
        pausieren(dauer);
        System.out.println("Thread "+x.getName()+" beendet die Methode synchron().");
    }
    public static void nicht_synchron(Thread x,long dauer)
    {
        System.out.println("Thread "+x.getName()+" startet die Methode nicht_synchron().");
        pausieren(dauer);
        System.out.println("Thread "+x.getName()+" beendet die Methode nicht_synchron().");
    }
    public static void main(String[] args)
    {
        MeinThread mA = new MeinThread("A");
        MeinThread mB = new MeinThread("B");
        mA.start();
        mB.start();
        pausieren(300);
        while(mA==Thread.currentThread());        
        mA.stop();
        while(mB==Thread.currentThread());        
        mB.stop();
    }
}

Code 0-2: Hauptprogramm.java - erzeugt zwei Objekte der Klasse MeinThread.java und startet deren Methode "run()".

Ablauf der Aufrufe der synchronisierten und der nicht synchronisierten Methode durch die beiden Threads.

Bild 0-1: Ablauf der Aufrufe der synchronisierten und der nicht synchronisierten Methode durch die beiden Threads.

Übung 2

Aufgabe 1

Schreiben Sie basierend auf thread003 ein Java-Programm, bei dem von einem Thread A immer wieder eine Reihe von 100 Meßwerten in ein Array geschrieben werden und diese von einem Thread B immer wieder komplett ausgelesen und auf der Kosnole ausgegeben werden.

  • Lesen und Schreiben der Meßwerte soll über die gleiche synchronisierte Methode erfolgen.
  • Die Meßwerte werden natürlich von Thread A nicht wirklich erfaßt, sind also Dummy-Zahlen.
  • Dennoch sollen sich die Werte immer wieder ändern, z.B. bei geraden Indices an Aufrufen lauter 0er, bei ungeraden 1er.
  • Verwenden Sie testweise Ihre Methode auch einmal nicht synchronisiert, um die sich dabei ergebenden Probleme sichtbar zu machen.
Beispiellösung zu Aufgabe 1.

Aufgabe 2

Schreiben Sie ein Java-Programm, bei dem die Instanzen eines Threads einzelne Quadratzahlen berechnen. Nachdem alle fertig sind, soll die Gesamt-Summe ausgegeben werden.

Nutzen Sie die Thread-Methode "isAlive()", um zu gewährleisten, dass die Ergebnisse aller Threads vorliegen.

Verwenden Sie sleep(), um die Berechnungszeit jedes Threads künstlich zu verlängern.

Beachten Sie, dass hier in der run()-Methode keine Endlosschleife steht.

Aufgabe 3

  • Identifizieren Sie anlehnend an Übung 1 die bei den COACH-Vehikeln auftretenden Teilprozesse und organisieren Sie diese in einem Prozessfluss-Diagramm.
  • Erweitern Sie das ganze auf einen Vehikelschwarm, der in Verbindung mit einem zentralen Rechner steht.