0

スレッド内に次のメソッドがあり、100%動作しますが、コードを削除するSystem.out.println("here");と、コードの実行が停止します。エラーはなく、何もしていないように見えます。これにより、画像の色が明るくなり、デバッグラインが明るくなりますが、それがないと明るくなりません。なぜそれを引き起こしているのですか?

スレッドクラス:

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

そして、ダイアログボックス関連のコード:

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

1 に答える 1

1

this.amountとして宣言されていvolatileますか?

このフィールドは、別のスレッドでの割り当てによって変化すると思います。として宣言されていない場合、上記のメソッドを実行しているスレッドがその変更を監視するvolatileと想定する理由はありません。run()に初めて割り当てた後はthis.amountcAmountとにかく、このスレッドの観点からは、それらは同じままです。

宣言された修飾子を明確にし、this.amount他の場所で変更されたコードのスニペットを表示したら、必要な動作を復元するために必要な適切な同期デバイスを指定するのに役立ちます。

の呼び出しがここで違いを生むように見える理由についてはPrintStream#println()、遅延を引き起こすだけでなく、変更がこのスレッドに表示されることを可能にするメモリ可視性エッジの前に発生する可能性があります。this.amountそれは多くの手振りですが、その特定の副作用の根本原因を突き止める前に、最初に解決する必要があるより大きな問題があると思います。

于 2012-11-18T00:36:44.060 に答える