3.5: Picasso

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.

3.5: Picasso
Hallo miteinander,

ich hätte da paar kleine fragen zu der Aufgabe 3.5: Picasso, und zwar frage ich mich:

  1. Muss/Darf man das mit einem ExecutorService machen inkl. einer selbsterstellten Runnable-klasse die Runnable implementiert?

  2. heisst es in der Aufgabenstellung bei der a)

… soweit ich sehe kann man punkte mit der methode „public synchronized void colorize(final int x, final int y, final int color)“ aus der klasse „Canvas“ färben, jedoch frage ich mich was sollte ich am besten für x und y einsetzen damit die Punktauswahl auch wirklich zufällig ist? etwa eine zahl die sich an Math.random() bedient? :scared:


Nein, es ist von Threads die rede nicht von Arbeitspaketen, das schließt den ExecutorService aus.

Jep oder besser man erstellt sich ein eigenes Random Objekt.


hallo,
kann mir vlt. jemand sagen warum mein picassoTest immer “no JUnit tests” ausspuckt?


ich hätte da auch noch eine weitere frage zur implementierung, so weit habe ich jetzt alles umgesetzt und es läuft denke ich auch wie es sollte

jedoch finde ich es bei mir relativ unschön dass ich für jede Teilaufgabe eine eigene Thread-klasse erstellt habe die in der run()-methode eben das umsetzt was verlangt ist.
ich hatte versucht in der Methode “synchronizedPaint” die Methode “randomPaint” aufzurufen und die run()-Methode die eben in “randomPaint” eigentlich angewendet wird zu überrscheiben, aber irgendwie habe ich das nicht geschafft… geht das überhaupt? und wenn ja wie?


So global ist es schwierig da was zu machen. Also in der synchronizedPaint die RandomPaint aufzurufen ist keine gute Idee, weil dann eben nicht mehr den Synchronized-Block einbauen kannst.

Es gäbe aber theoretisch verschiedene Möglichkeiten:

  1. Man könnte aus beiden Methoden eine einzelne machen, die einen zusätzlichen Parameter bekommt (isSynchronized) und abhängig von diesem Parameter wird dann entweder ein synchronisierter Thread erstellt oder ein nicht synchronisierter. Das kannst du aber nicht machen, weil du keine Methodensignaturen verändern darfst.

  2. Man könnte ähnliche Vorgänge in ausgelagerte Methoden packen, die dann von allen Teilaufgaben aufgerufen werden können.

In dieser Aufgabe geht es aber primär darum die wirklichen Unterschiede zwischen synchronisierten und nicht synchronisierten Code zu erkennen. Deshalb müsst ihr hier vieles doppelt coden. In der Praxis würde man eher auf Möglichkeit 1 zurückgreifen, wobei die erste Teilaufgabe ja in der Praxis sowieso nie verwendet werden sollte, weil sie fehlerhaft ist. Die Aufgabe soll euch einfach mit verschiedenen Synchronisationsmöglichkeiten warm werden lassen und da ist es am einfachsten, wenn ihr kein Komplexes-Methoden und Klassennetz vorfindet, sondern die drei Methoden einfach unabhängig voneinander implementiert.


Ich habe das bisher für die randomPaint() und synchronizedPaint() so gelöst, wie auf dem Übungsblatt 3 in der Präsenzübung. Also in einer Schleife eine Reihe von neuen Thread Objekten erstellt, die in einer überschriebenen run() Methode den Code zum färben ausführen.
Das funktioniert, soweit man sein Canvas Objekt final macht und zum zählen der Threads (id) eine Klassenvariable von PicassoImpl benutzt.
Allerdings macht mich folgendes stutzig, ob das wirklich korrekt ist:

Alle meine Bilder haben massiv überwiegendem anteil die Farbe rot (die erste Farbe im Farb-Array der Canvas Klasse). Teilweise sind da nur wenige Punkte mit einer anderen Farbe (). Läuft da irgendwas falsch?


Bin mir gerade nicht ganz sicher, wozu du das Canvas Objekt final und die id als Klassenvariable machen willst. Uebergib doch einfach deinem Thread seine jeweilige id und das Canvas-objekt, funktioniert bei mir einwandfrei. (denk dran, die einzelnen Methoden arbeiten nicht auf dem selben Canvas sondern jeweils auf ihrem eigenen neu erstellten)

Mach vor allem mal die syncFreePaint fertig, da siehst du am besten ob deine ID-zuweisung klappt. (oder lass dir die ID anzeigen/ausgeben)

(dann siehst du ob du irgendwo zu viel Rot, d.h. die ID 0, hast)


Wie genau stellt man das dann an? Ich hab’s auch so wie in der Übung, also nach diesem Schema gemacht (Der Code ist aus den Übungsfolien und hat nichts mit der Picasso-Aufgabe zu tun)
for (int i = 0; i < 5; i++) {
new Thread() {
@Override
public void run() {
System.out.println("This is Thread " + a);
a++;
}
}.start();

und wenn man das so macht, meckert eclipse, dass es in der inneren Klasse nicht mit nicht-final Objekten/Variablen umgehen kann. Darum muss man das dann alles final deklarieren, wenn man das so machen will. Mich würde aber auch interessieren, wie man’s anders/besser machen kann.


kann ich bei der syncFreePaint dem letzten Thread der erstellt wird einfach alles was übrig bleibt aufhalsen? oder muss ich das nochmal verteilen

z.B.
100 Felder, 7 threads, die ersten 6 arbeiten jeweils 14 ab (84 gesamt) und der 7. Thread 16


Zwar off topic, aber trotzdem hier ne meiner Meinung nach bessere Version ;):

public class A {
  class MyThread extends Thread {
    int a;

    public MyThread(int a) {
      this.a = a;
    }

    @Override
    public void run() {
       System.out.println("This is Thread " + a);
    }
  }

  public void foo() {
    int a = 0;
    for (int i =0; i < 5; i++) {
       new MyThread(a).start();
       a++;
    }
  }
}

Ne kurze, schwer lesbare Version war ja nicht verlangt :cool:.

1 Like

So eine Aufteilung ist okay ;).


Im prinzip was pug gepostet hat, eigene Threadklasse erstellen mit Parameter-Konstruktor, und dem dann alles gewünschte beim erstellen mitgeben :wink:

Hab nun auch noch eine Frage, spielt es eine Rolle ob ich wie in pugs Beispiel

Threaderstellung + start im selben Schleifendurchlauf mache, oder wie im Code-Beispiel aus MyThread etc. von der Übungsseite erstmal alle erstellen (in nem array speicher, brauch ich eh fürs joinen), dann starten, und am ende joinen?


Erstellung und [m]start()[/m] kannst du in der gleichen Schleife durchführen. Für [m]join()[/m] brauchst du dann natürlich eine eigene.

1 Like

PFP ist cool!

Postet doch mal euer freepaint :slight_smile:

(das hier war: 900 Threads auf 100 * 100)

Macht definitiv mehr spaß als langweiliges AuD


Passt ja garnicht auf deinen Bildschirm! :smiley:

Hier auch 900 Threads 100x100 - meine Version.


Also versteh ich das richtig, dass man die Klasse Java.util.Random verwenden dafür verwenden darf…?


Ja das darfst du. Lies aber auch den Artikel in der Java-API dazu durch, wo auch was über die parallele Verwendung drin steht, was du beachten solltest.

1 Like

Alles klar, danke :slight_smile:


Ich habe mich für abwechselnde Pixel entschieden :slight_smile: http://imgur.com/McIMzbS

1 Like