Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
Aufgabe 3.5
Hallo,
ich verstehe nicht, wo bei Aufgabe 3.5 der Unterschied zwischen Teil a und Teil b liegt. Wenn ich nur Teil b implementiere, dann kann ich doch den selben Code auch für Teil a verwenden, oder?
Außerdem würde ich gerne wissen, ob ich die .concurrent Files importieren darf ^^
Danke für alle Antworten!
Beides ist natürlich ähnlich.
Aber bei der b) sollst du den kritischen Abschnitt schützen.
Die Bedingung erlaubt keinen sinnvollen Schutz vom kritischen Abschnitt.
Klar.
Ok, danke, aber da steht doch auch, dass ein Punkt nur beschrieben wird, wenn er noch unbeschrieben ist. Widerspricht das nicht der Aussage, dass jeder Punkt beleibiebig oft beschrieben werden könnte?
Nein Probiers einfach mal aus. Wegen der laesstigen Nebenlaeufigkeit ohne Schutz des kritischen Abschnitts ist die Aussage kein direkter Widerspruch
bei der c):
Im der Dokumentation von syncFreeCode steht ‘Randomly writes matrix code on a screen, avoids collision without synchronization’
im Aufgaben blatt steht
‘Es ist nicht mehr notwendig, dass die Threads die Punkte zufällig auswählen. Achten Sie auf eine möglichst gute Arbeitsaufteilung und die parallele Ausführung.’
Was soll man jetzt machen?
Mir fällt zwar spontan auch eine Lösung für ‘Randomly without synchronization’ ein, die ist dann aber nicht mehr so sehr parallel.
Soll man hier noch nach einer parallelen, zufällig-organisierter, nicht synchronisierter Lösung suchen, reicht das erfüllen einer der beiden vorgaben, oder hat eine Vorgabe Vorrang (z.B. Aufgabenblatt erfüllen, Doku ignorieren oÄ) ?
Um alle Klarheiten zu beseitigen, wurde Randomly aus den Kommentaren zur syncFreeCode entfernt.
danke
Hallo zusammen,
ich bin noch etwas verwirrt wegen der synchronisation bei der b). Wir hatten in der Vorlesung auf Folie 4-13 das Beispiel der Vector-Klasse, wo die Abfrage, ob das Element enthalten ist, und das Einfügen synchronisiert wurde. Als Marke wurde das Object “vector” selbst verwendet. So ähnlich wird es ja dann auch in unserer Aufgabe zu machen sein. Nur stand daneben mit einem Blitz: immer noch nicht sicher, falls Vector eine private Marke verwendet.
Was bedeutet das jetzt für uns? Ich hätte jetzt eine eigene Methode mit synchronized sicherheitshalber geschrieben für Abfrage und Einfügen. Wäre das thread-sicher? Oder geht es hier auch wie auf der Folie, da das Array in der MatrixScreen Code public ist? Ich habe wohl auch das Problem, dass hier auf der Folie beschrieben ist, noch nicht ganz verstanden.
Vielen Dank schonmal und weiterhin ein schönes Wochenende.
Okey, habe beim programmieren gemerkt, dass ich auf das “array”-Objekt gar nicht zugreifen darf. Aber nehme ich dann einen Block mit Screen Objekt als Marke oder eine eigene synchronized Funktion. Oder ist beides hier äquivalent. Aus der Vorlesung ist mir einfach das beschriebene Problem aus Folie 4-13 nicht ganz klar geworden, und hier ist es ja doch irgendwie ein ähnlicher Fall…
It’s complicated und geht darüber hinaus, was man für Aufgabe 3.5 braucht. Ich versuch es trotzdem zu erklären.
Also angenommen ich hätte eine Vector Klasse die so aussieht:
public class Vector {
private MyLock lock = new MyLock();
public boolean contains(Object ele) {
synchronized (lock) {
// Ist das Objekt im Vector?
}
}
public void add(Object ele) {
synchronized (lock) {
// Element einfuegen
}
}
}
Danach schreibe ich mein Programm so:
public class Test {
public static class MyThread1 extends Thread {
public Vector vector = null;
public Object ele = null;
public MyThread1(Vector v, Object e) {
vector = v;
ele = e;
}
public void run() {
synchronized(vector) {
if (!vector.contains(ele)) {
vector.add(ele);
}
}
}
}
public static class MyThread2 extends Thread {
public Vector vector = null;
public Object ele = null;
public MyThread2(Vector v, Object e) {
vector = v;
ele = e;
}
public void run() {
vector.add(ele);
}
}
public static void main(String args) {
Vector v = new Vector();
Object e = new Element();
MyThread1 thread1 = new MyThread1(v,e);
MyThread1 thread1_2 = new MyThread1(v,e);
MyThread2 thread2 = new MyThread2(v,e);
thread1.start();
thread2.start();
}
}
Wie man hier sieht, kann es zwischen Instanzen von MyThread2
und den Instanzen von MyThread1 zu Wettlaufsituationen kommen.
Das Problem ist, dass die Vector-Klasse ein private Marke (lock)
verwendet.
Es gibt mehrere Möglichkeiten, das zu lösen:
- Bei run() von MyThread2:
public void run() {
synchronized(vector) {
vector.add(ele);
}
}
ODER
- Die private Marke öffentlich machen und verwenden:
public class Vector {
public final MyLock lock = new MyLock();
...
}
public class MyThread1 {
synchronized(vector.lock) {
...
}
}
ODER
- Anstatt einer privaten Marke, die Vector-Instanz als Marke verwenden:
public class Vector {
public synchronized boolean contains(Object ele) {
// Ist das Objekt im Vector?
}
public synchronized void add(Object ele) {
// Element einfuegen
}
}
Alle 3 Varianten kommen vor, es ist also nicht so, dass eine Variante immer besser wäre als die anderen ;).
Bei Aufgabe 3 reicht es, einfach die gleiche Marke bei allen Threads zu verwenden. Welche das ist, ist egal ;).
wow, vielen Dank für die ausführliche Antwort. In der Vorlesung wurde mir das so nicht klar. Danke.