Lassen Sie uns sagen, ich habe zwei Threads wie folgt ausgeführt werden:Funktioniert dieses nicht standardmäßige Java-Synchronisationsmuster?
- Thread A, die Berechnung durchführt, während Pixel eines gemeinsamen Bildes
- Thema B periodisch liest das Bild und kopiert sie auf den Bildschirm zu aktualisieren
Thread A führt die Arbeit schnell aus, sagen 1 Million Aktualisierungen pro Sekunde, also vermute ich, dass es eine schlechte Idee wäre, auf einem Lock/Mutex/Monitor so oft zu sperren und zu entsperren. Aber wenn es keine Sperre und keine Möglichkeit gibt, eine Vorkommnis-Beziehung von Thread A zu Thread B herzustellen, ist Thread B durch das Java-Speichermodell (JMM-Spezifikation) nicht garantiert, irgendwelche der A-Aktualisierungen des Bildes zu sehen.
So dachte ich, dass die minimale Lösung für Threads A und B ist, um beide regelmäßig auf der gleichen freigegebenen Sperre zu synchronisieren, aber keine Arbeit ausführen, während im synchronisierten Block - das ist, was das Muster nicht-Standard und macht zweifelhaft. Zur Veranschaulichung in Halbechthalb Pseudo-Code:
class ComputationCanvas extends java.awt.Canvas {
private Object lock = new Object();
private int[] pixels = new int[1000000];
public ComputationCanvas() {
new Thread(this::runThreadA).start();
new Thread(this::runThreadB).start();
}
private void runThreadA() {
while (true) {
for (1000 steps) {
update pixels directly
without synchornization
}
synchronized(lock) {} // Blank
}
}
private void runThreadB() {
while (true) {
Thread.sleep(100);
synchronized(lock) {} // Blank
this.repaint();
}
}
@Override
public void paint(Graphics g) {
g.drawImage(pixels, 0, 0);
}
}
Does leer Synchronisationsblöcke auf diese Weise das Hinzufügen korrekt den Effekt erreichen von Daten von Thread A übertragen einzufädeln B? Oder gibt es eine andere Lösung, die ich mir nicht vorstellen konnte?
Warum würde ein atomarer Boolescher nicht den Trick machen? Synchronisieren auf nichts verlässt immer noch die Arbeit aus der Synchronisation – efekctive
Warum nicht 'volatile' verwenden? – shmosel
Möglicherweise verwandt: http://StackOverflow.com/Questions/17108541/Happens-before-relationsshifts-with-Volatile-Fields-and-Synchronized-blocks-in-Jav – flakes