2012-12-01 6 views
0

나는 지속적으로 업데이트되는 데이터를 그리려는 프로그램이 있습니다. (우연히 microhpone-line-data입니다.) 데이터는 8000 길이의 복식 배열입니다. 페인트 방법을 사용하는 사이에 오버라이드되는 '손실'데이터는 신경 쓰지 않습니다.Java 그래픽 동기화에서 동적 데이터 그리기 문제가 발생했습니다.

필자의 순진한 구현에서는 페인팅 루틴이 진행되는 동안 오디오 데이터가 업데이트되는 동기화 문제가 발생한다는 것을 알게되었습니다.

나는 자바와 동시성 패키지에 대해 약간 구식이라고 알고 있지만, 첫 번째 응답은 공유 된 데이터 코드 주위에 동기화 된 블록을 두는 것이었다. 당연히 이는 그래픽 스레드를 가끔 차단하므로 아마도이 작업을 수행하는 데 더 좋은 방법이있을 것이라고 생각합니다.

필자는 기본적으로 동기화에 대한 경험이별로 없으며 어딘가에 약간의 문제를 일으키고 있습니다. 이 문제를 더 잘 이해하고있는 누군가가 그래픽 스레드를 차단하지 않는보다 세련된 솔루션을 제안 할 수 있을지 궁금합니다.

내 순진 코드 : 좀 더 지능적인 사람이 더 나은 뭔가를 제공 할 수 있습니다하지 않는 한

Object lock = new Object(); 
double[] audio = new double[8000] 

// array size is always exactly 8000 
public update(double[] audio) { 
    synchronized(lock) { 
     this.audio=audio; // and some brief processing 
    } 
    repaint(); 
} 

public void paint(Graphics g) { 
    synchronized(lock) { 
     // draw the contents of this.audio 
    } 
} 

답변

0

자기 대답은, 그냥 다음, 루틴의 시작 부분에 오디오 배열에 대한 참조를 저장하고 그에서 그릴 오디오 버퍼에 대한 모든 업데이트는 별도의 배열에서 계산을 수행 한 다음 this.audio를 새 배열에 한 번에 할당합니다.

페인트 루틴이 가끔씩 깜박 거리지 만 작동하지 않는 것처럼 보이지만 동기화 블로킹으로 인해 시간의 약 10 %가 눈에 띄게 깜박입니다. 오디오 데이터는 드로잉 루틴의 중간 단계로 업데이트되지 않습니다. 그래서 ... 문제가 해결되었습니다. 아마.

double[] audio = new double[8000] 

// array size is always exactly 8000 
public update(double[] audio) { 
    // do any brief processing 
    this.audio=audio; // the reference is re-assigned in one step 

repaint(); 
} 

public void paint(Graphics g) { 
    audioNow = this.audio; // save the reference 
    // draw the contents of audioNow (not this.audio) 
}