2016-04-10 21 views
0

Basit bir z80 makinesine öykünmesi gereken çok iş parçacıklı bir uygulama yazıyorum ve ekran bölümü ile ilgili sorun yaşıyorum. Tüm video işlemlerini ayrı bir iş parçacığında işlemek için bir JPanel ve bir DSP sınıfı genişleten bir Ekran sınıfım var.Java int dizi içerik tutmuyor

Araştırmayı incelemek için println()'u kullandıktan sonra, sorunun DSP sınıfındaki sonuç verilerini Screen sınıfındaki bir çerçeve arabelleğe kopyaladığını belirledim. DSP ekrana yazdığında, dizi, bileşenin tamamı gelene kadar veriyi saklar ve dizinin tamamı silinir ve ekran siyah kalır. Aşağıda, Screen sınıfı için kodum var, çünkü DSP sınıfının olması gerektiği gibi çalıştığını biliyorum. Yorumlanan baskı çizgileri, tüm beyaz piksellerin çerçeve arabelleğine yazılması için DSP'ye başvurmaktadır.

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

Ben SwingUtilities.invokeLater() yöntem haline yazma kodunu çevreleyen denedi, ama bu sadece neden önemli gecikme ve meseleyi çözmedi var. Birisi bana ne yapmakta olduğumu bulmama yardım edebilir, çünkü fikirlerim yok.

+0

'synchronised'? Veya 'AtomicBoolean'? – MadProgrammer

cevap

0

Sorun, büyük olasılıkla iş parçacıkları arasındaki bellek erişimini düzgün şekilde eşitlemediğinizdir. Sonuç olarak, DSP iş parçacığı büyük olasılıkla verilerini işlemci önbelleğine yazar, ancak diğer iş parçacıklarının görmesi için ana belleğe boşaltılmak yerine veriler atılır.

Bir şekilde memory dizisine erişimi eşitlemeniz gerekir. Bunu yapmanın en kolay yolu, synchronized numaralı paintComponent ve writeData yöntemlerini yapmaktır. Özel uygulamanızın nasıl davrandığına bağlı olarak, bu sizin tercih edeceğinizden daha fazla çekişmeye neden olabilir. Bu nedenle, daha karmaşık bir yaklaşımla bazılarına gereksiniminiz olabilir, ancak bir iş parçacığında yazılmış verilerin görünür hale gelmesini istediğinizde bazı eşitleme yöntemleri gerekir. diğer konular.

+0

Tamam, daha önce hiç senkronize kullanmadım, bu yüzden bunu öğrenmek zorundayım. Sonuçlarımı size bildiririm. – Jaca