0

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);
    }
}
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • Never compare floats in this way! See http://stackoverflow.com/questions/1088216/whats-wrong-with-using-to-compare-floats-in-java – Michał Ziober Nov 17 '12 at 23:54
  • There doesn't appear to be anything wrong here. Are you sure the `System.out.println` line is the only thing that changes? – Brian Willis Nov 17 '12 at 23:55
  • yup, I ran it with it un-commented and it worked. Stopped it then commented it out and ran it again and it didn't work. I the un-commented it and it worked. – Get Off My Lawn Nov 18 '12 at 00:05
  • I replaced `System.out.println` with `sleep(1);` and that fixed it, but my editor is say that doing that isn't a good idea. Is it not? – Get Off My Lawn Nov 18 '12 at 00:28
  • See: [Loop doesn't see changed value without a print statement](https://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without-a-print-statement) – Boann Dec 29 '14 at 09:16

1 Answers1

1

Is this.amount declared as volatile?

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 the run() method above will ever observe a change to it. After the first time you assign this.amount to cAmount, they remain equal thereafter—from the point of view of this thread, anyway.

Once you clarify for us the declared qualifiers on this.amount and 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 to this.amount to 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.

seh
  • 14,999
  • 2
  • 48
  • 58