我在一个线程中有以下方法,并且它可以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);
}
}
答案 0 :(得分:1)
this.amount
被声明为volatile
吗?
我认为这个字段由于在另一个线程中的赋值而发生了变化。如果它没有被声明为volatile
,则没有理由认为运行上述run()
方法的线程会观察到对它的更改。在您第一次将this.amount
分配给cAmount
之后,无论如何,从此线索的角度来看,它们保持相等。
一旦您在this.amount
上为我们澄清了声明的限定符并显示其他地方更改的代码片段,我们就可以帮助指定恢复所需行为所需的正确同步设备。
至于为什么PrintStream#println()
的调用似乎在这里产生了影响,它可能不仅导致延迟,而且可能还会触及发生在内存可见性边缘之前允许更改为this.amount
以使此线程可见。这是很多挥手,但我认为在解决特定副作用的根本原因之前,首先要解决更大的问题。