Get Off My Lawn
Get Off My Lawn

Reputation: 36299

Loop doesn't execute inner if statement

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);
    }
}

Upvotes: 0

Views: 116

Answers (1)

seh
seh

Reputation: 15259

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.

Upvotes: 1

Related Questions