Petrinetze

Jensons Art

Mitglied
Hallo zusammen,

ich weiss leider nicht weiter. Einige Teilaufgaben konnte ich lösen, doch hier weiß ich leider nicht mehr weiter;

Es sollen Banktransaktionen von drei Akteuren namens ”Firma”, ”Oma” und ”Ich” mit
Java programmiert werden, die konkurrierend auf ein Konto zugreifen. Das Konto hat
einen Kontostand und es finden Überweisungen bzw. Auszahlungen am Bankautomaten
statt. Vor einer Buchung wird immer der Kontostand abgefragt. Das Szenario:

- ”Firma” überweist mehrmals 1000 Euro
- ”Oma” überweist mehrmals 50 Euro
- ”Ich” hebt mehrmals 250 Euro ab


Führen Sie die Simulation der Banktransaktionen (mit/ohne Synchronisierung) mit Java-Threads durch und stellen Sie die Prozesse als Petrinetz dar. Untersuchen Sie eine alternative Implementierung mit dem Aktorenmodell.

Für Tipps und Hinweise wie man hier vorgeht, wäre ich sehr dankbar.

Danke und Gruß
Anna
 

Blut1Bart

Bekanntes Mitglied
Ohne Synchronisierung sollte das Konto einen geringeren Betrag aufweisen, als tatsächlich vorhanden ist.

Petrinetze sind ganz simpel. Schau dir mal Beispielmodelle auf wikipedia an.

Was hast du bis jetzt versucht?
 

Blut1Bart

Bekanntes Mitglied
Hallo,

sorry ich war zeitlich verhindert.

Der Java Code (ohne Synchronisation) könnte so aussehen:
Java:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class Bank {
    private final Konto konto1 = new Konto();
    private final List<Akteur> akteure = new ArrayList<>();

    public static class Konto {
        int betrag = 0;

        void transaktion(int betrag) {
            this.betrag += betrag;
        }

        public int getBetrag() {
            return betrag;
        }
    }

    public class Akteur {
        String name;
        int betrag;

        public Akteur(String name, int betrag) {
            this.name = name;
            this.betrag = betrag;
        }

        void execute() {
            if (betrag > 0) {
                System.out.println(name + " überweist " + betrag);
            } else {
                System.out.println(name + " hebt " + betrag + " ab");
            }
            konto1.transaktion(betrag);
        }
    }

    public Bank() {
        akteure.add(new Akteur("Firma", 1000));
        akteure.add(new Akteur("Oma", 50));
        akteure.add(new Akteur("Ich", -250));
    }

    public void szenario() {
        akteure.forEach(Akteur::execute);
    }

    public void simulation() throws InterruptedException {
        long stop = System.currentTimeMillis() + 1000;
        AtomicInteger counter1 = new AtomicInteger(0);
        AtomicInteger counter2 = new AtomicInteger(0);
        Thread t1 = new Thread(() -> {
            while (System.currentTimeMillis() < stop) {
                szenario();
                counter1.incrementAndGet();
            }
        });
        Thread t2 = new Thread(() -> {
            while (System.currentTimeMillis() < stop) {
                szenario();
                counter2.incrementAndGet();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        int c = counter1.intValue() + counter2.intValue();
        System.out.println("Iteration: " + c + ", soll: " + c * 800 + ", ist: " + konto1.getBetrag());
    }

    public static void main(String[] args) throws InterruptedException {
        Bank bank = new Bank();
        bank.simulation();
    }
}

Ausgabe ist dann z B:
Code:
...
Ich hebt -250 ab
Ich hebt -250 ab
Firma überweist 1000
Oma überweist 50
Ich hebt -250 ab
Firma überweist 1000
Oma überweist 50
Ich hebt -250 ab
Iteration: 32556, soll: 26044800, ist: 26045050

Und hier zeigt sich das Problem, Soll und Ist stimmen nicht überein (würde man einen double-Betrag wählen noch viel schlimmer).

Was müsstest Du jetzt tun, damit es synchronisiert wäre?

... und bei den Petri-Netzen hast Du Dir nicht viel Mühe gegeben...
 

Neue Themen


Oben