2016-04-10 15 views
0

私は単純なz80マシンをエミュレートするためのマルチスレッドアプリケーションを作成していますが、表示部分に問題があります。私はJPanelを拡張するScreenクラスと、別のスレッド上のすべてのビデオ処理を処理するDSPクラスを持っています。Java int配列に内容が保存されていません

調査のために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()メソッドへの書き込みコードを囲む試してみましたが、それはただの大きな遅れを引き起こし、問題を解決していません。私はアイデアがないので、誰かが私が握っていることを見つけるのを助けることができますか?

+0

'synchronised'?または 'AtomicBoolean'? – MadProgrammer

答えて

0

スレッド間のメモリアクセスが正しく同期されていない可能性があります。その結果、DSPスレッドはそのデータをプロセッサキャッシュに書き込む可能性が最も高いですが、他のスレッドが参照できるようにメインメモリにフラッシュされる代わりに、データは破棄されます。

何らかの形でmemoryアレイへのアクセスを同期させる必要があります。これを行う最も簡単な方法は、paintComponentwriteDataの両方の方法を​​にすることです。特定のアプリケーションがどのように動作するかによって、競合が発生する可能性がありますので、より洗練された方法で解決する必要がありますが、あるスレッドに書き込まれたデータを他のスレッド。

+0

さて、以前は同期を使ったことがないので、それを学ばなければなりません。私はあなたに私の結果を知らせます。 – Jaca

関連する問題