【问题标题】:Java int array not keeping contentsJava int 数组不保留内容
【发布时间】:2016-04-10 03:04:53
【问题描述】:

我正在编写一个用于模拟简单 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() 方法中,但这只是造成了严重的延迟,并没有解决问题。有人可以帮我找出我在做什么,因为我没有想法。

【问题讨论】:

  • synchronised?还是AtomicBoolean

标签: java multithreading swing


【解决方案1】:

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

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

【讨论】:

  • 好的,我以前从未使用过同步,所以我必须学习一下。我会让你知道我的结果。
猜你喜欢
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多