Announcement

Collapse
No announcement yet.

Frage zur Nebenläufigkeit bei Threads

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Frage zur Nebenläufigkeit bei Threads

    Hallo,

    ich habe ein Verständnisproblem bei der Anwendung von Threads.

    Ich habe zunächst eine Klasse erstellt, die eine dynamisch erweiterbare Liste für Personen-Objekte bereitstellt. Die Klasse habe ich dafür allerdings nicht von ArrayList abgeleitet, da ich leidglich Methoden zum Hinzufügen, Entfernen und Abrufen von Elementen benötige.

    Code:
    public class Person {
      private String firstname;
      private String lastname;
    
      public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
      }
    
      ...
    }
    
    public class PersonList {
      private ArrayList<Person> internalList;
     
      public PersonList() {
        internalList = new ArrayList<Person>();
      }
    
      public void add(Person p) {
        internalList.add(p);
      }
    
      public Person get(int index) {
        return internalList.get(index);
      }
    
      public void remove(int index) {
        internalList.remove(index);
      }
    }
    Als nächstes habe ich eine Klasse von Thread abgeleitet, die eine Referenz der Personenliste hält und noch weitere Aktionen ausführt, die aber erstmal nicht weiter von Bedeutung sind.

    Code:
    public class MyThread extends Thread {
      private PersonList plist;
    
      public MyThread(PersonList plist) {
        super();
        this.plist = plist;
      }
    
      public void run() {
      ...
      }
    }
    Zum Schluss habe ich das Hauptprogramm, das in seinem Verlauf unter bestimmten Umständen Threads abspaltet.

    Code:
    public class Demo {
      private PersonList plist;
    
      public Demo() {
        plist = new PersonList();
        plist.add(new Person("Max", "Mustermann"));
      }
    
      public void start() {
        MyThread t1 = new MyThread(plist);
        MyThread t2 = new MyThread(plist);
        t1.start();
        t2.start();
      }
    
      public static void main(String[] args) {
        Demo demo = new Demo();
        demo.start();
      }
    }
    Nun zu meinen Fragen...

    Als erstes würde mich interessieren, ob die Thread-Objekte jetzt jeweils die selbe Liste besitzen. Theoretisch müsste das ja so sein, da ich bei der Instanziierung der Objekte keine Kopie der Liste erzeuge sondern lediglich eine Referenz auf die in Demo enthaltene Liste übergebe. Das heißt, wenn t1 die Liste verändert, hat t2 die geänderte Liste auch oder liege da falsch?

    So und damit entsteht ja dann das Problem der Nebenläufigkeit. Dafür gibt es das Schlüsselwort synchronized, mit dem ich die Methoden add, get und remove versehen könnte:
    Code:
    public class PersonList {
      private ArrayList<Person> internalList;
     
      public PersonList() {
        internalList = new ArrayList<Person>();
      }
    
      public synchronized void add(Person p) {
        internalList.add(p);
      }
    
      public synchronized Person get(int index) {
        return internalList.get(index);
      }
    
      public synchronized void remove(int index) {
        internalList.remove(index);
      }
    }
    Dann können zwei Thread-Objekte zumindest erstmal nicht gleichzeitig Objekte aus der Liste entnehmen oder hinzufügen.
    Aber was passiert bei folgendem Szenario: t1 entfernt per remove() das Objekt an Position 10 aus der Liste und t2 ruft zur selben Zeit per get() das Objekt ebenfalls an Position 10 ab? Theoretisch müsste ich zu diesem Zweck doch die gesamte ArrayList sperren oder? Wie müsste ich dazu vorgehen und produziert diese Lösung nicht dann unter Umständen einen Flaschenhals, wenn viele Thread-Objekte die Personenliste bearbeiten wollen?

    Ich danke euch schon im Voraus für eure Antworten.

    Viele Grüße

  • #2
    "Als erstes würde mich interessieren, ob die Thread-Objekte jetzt jeweils die selbe Liste besitzen."
    ja

    "So und damit entsteht ja dann das Problem der Nebenläufigkeit. Dafür gibt es das Schlüsselwort synchronized, mit dem ich die Methoden add, get und remove versehen könnte:...Dann können zwei Thread-Objekte zumindest erstmal nicht gleichzeitig Objekte aus der Liste entnehmen oder hinzufügen."
    Nein, ein Thread kann nicht gleichzeitig auf die Liste zugreifen. Es ist zielführender die Liste selbst threadsicher zu machen und nicht die Methoden in irgendwelchen Klassen

    List list = Collections.synchronizedList(new ArrayList(...));
    http://docs.oracle.com/javase/6/docs...ArrayList.html

    Das dann jemand warten muss beim Zugriff auf die Liste, wenn jemand anders die in Benutzung hat, ist dann halt so. Das wirst du allerdings kaum merken
    Christian

    Comment

    Working...
    X