I have the following method within a thread, and it works 100%, but once I remove System.out.println("here"); the code stops doing what it was doing. There are no errors, it just has the appearance of not doing anything. What this does is brightens the colors of an image, with the debug line in it brightens, without it, it doesn’t brighten. Why is it causing that?
The thread Class:
package pocketshop.threads;
import com.jogamp.opencl.CLBuffer;
import java.awt.Container;
import java.awt.image.BufferedImage;
import java.nio.FloatBuffer;
import pocketshop.Canvas;
import pocketshop.graphics.CL;
import pocketshop.graphics.Preview;
/**
*
* @author Ryan
*/
public class AdjustThread extends Thread {
protected float amount = 0;
protected CLBuffer<FloatBuffer> buffer;
protected String adjustment;
protected Container parent;
public AdjustThread(Container parent, String adjustment) {
this.parent = parent;
this.adjustment = adjustment;
}
public void setAmount(float amount){
this.amount = amount;
}
public CLBuffer<FloatBuffer> getBuffer() {
return buffer;
}
public void run() {
float cAmount = 0;
while(true){
System.out.println("here");
if(cAmount != this.amount){
cAmount = this.amount;
CL.start(adjustment, this.amount);
buffer = CL.getBuffer();
float[] pixels = CL.getPixels();
BufferedImage newimage = new BufferedImage(Canvas.image.getWidth(), Canvas.image.getHeight(), BufferedImage.TYPE_INT_RGB);
buffer.getBuffer().get(pixels).rewind();
newimage.getRaster().setPixels(0, 0, Canvas.image.getWidth(), Canvas.image.getHeight(), pixels);
Preview.setImage(newimage);
Canvas.preview = Preview.getImage();
parent.repaint();
}
}
}
}
And the Dialog box relevant code:
package pocketshop.dialogs;
import java.awt.image.BufferedImage;
import pocketshop.Canvas;
import pocketshop.graphics.adjustments.Contrast;
import pocketshop.threads.AdjustThread;
/**
*
* @author Ryan
*/
public class BrightnessContrastDialog extends javax.swing.JDialog {
AdjustThread adj;
/**
* Creates new form BrightnessContrastDialog
*/
public BrightnessContrastDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
adj = new AdjustThread(this.getParent(), "Brightness");
adj.start();
}
// Run everytime the JSlider moves
private void sldBrightnessStateChanged(javax.swing.event.ChangeEvent evt) {
float val = sldBrightness.getValue();
txtBrightness.setText("" + (int) val);
adj.setAmount(val);
}
}
Is
this.amountdeclared asvolatile?I take it this field changes by virtue of assignment in another thread. If it’s not declared as
volatile, there’s no reason to assume that the thread running therun()method above will ever observe a change to it. After the first time you assignthis.amounttocAmount, they remain equal thereafter—from the point of view of this thread, anyway.Once you clarify for us the declared qualifiers on
this.amountand show the snippet of code where it’s changed elsewhere, we can help specify the proper synchronization devices necessary to restore the behavior you desire.As for why the call to
PrintStream#println()seems to make a difference here, it’s likely causing not only a delay but may also be hitting a happens-before memory visibility edge that’s allowing the changes tothis.amountto become visible to this thread. That’s a lot of hand-waving, but I think that there are larger problems here to solve first before pegging the root cause for that particular side effect.