Java int数组不保留内容

时间:2016-04-10 03:04:53

标签: java multithreading swing

我正在编写一个多线程应用程序,用于模拟一个简单的z80机器,我在显示部分遇到问题。我有一个扩展JPanel的Screen类,以及一个DSP类来处理单独线程上的所有视频处理。

使用println()进行调查后,我确定问题是将结果数据从DSP类复制到Screen类中的帧缓冲区。当DSP写入显示器时,阵列会保留数据,直到需要绘制组件,整个阵列被擦除,屏幕保持黑色。下面是我的Screen类的代码,因为我知道DSP类的运行方式应该如此。评论的打印行是指DSP将所有白色像素写入帧缓冲区。

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 *
 * @author James
 */
public class Screen extends JPanel{
    private int[] memory = new int[153600];
    private int location = 0;
    private boolean writing;
    private BufferedImage img;
    private Timer timer;

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        int index = 0;
        for(int x = 319; x > 0; x--){
            for(int y = 1; y < 240; y ++){
                System.out.println(memory[index + 1]); // always prints zero
                int color = (memory[index] + (memory[index + 1] * 256));
                img.setRGB(x, y, convert16_32(color));
                index += 2;
            }
        }
        g.drawImage(img, 0, 0, this);
    }

    public void writeData(int d){//called from a seperate thread
        if(writing){
            memory[location] = d;
            location ++;
            if(location == 153600){
                location = 0;
                for (int n : memory) { //debug check to make sure the memory was properly written to
                    System.out.println(memory[n]);//prints 255 like it should
                }
                writing = false;
            }
        }
    }

    public void writeCommand(){
        writing = true;
    }

    public Screen() {
        img = new BufferedImage(320, 240, BufferedImage.TYPE_USHORT_565_RGB);
        timer = new Timer(1000/30, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (!writing) { //ensures screen is not updated when writing to memory
                    action();
                }
            }
        });
        timer.start();
    }

    private void action(){
        this.repaint();
    }

    private int convert16_32(int rgb) { // conerts 16 bit color to 32 bit color
        int r = ((rgb & 0xF800) << 16);
        int g = ((rgb & 0x07E0) << 11);
        int b = ((rgb & 0x001F) << 5);
        return (r | g | b);
    }
}

我已经尝试将编写代码包含在SwingUtilities.invokeLater()方法中,但这只会导致严重延迟并且无法解决问题。有人可以帮助我找到我正在做的事情,因为我没有想法。

1 个答案:

答案 0 :(得分:0)

问题很可能是您没有正确地同步线程之间的内存访问。因此,DSP线程很可能将其数据写入其处理器高速缓存,但是数据被丢弃而不是被刷新到主存储器以供其他线程查看。

您需要以某种方式同步对memory数组的访问。最简单的方法是将paintComponentwriteData方法都设为synchronized。根据您的特定应用程序的行为方式,这可能会导致比您希望的更多争用,因此您可能需要使用更复杂的方法,但是当您希望在一个线程中写入的数据可见时,需要一些同步方法其他线程。