2010-02-10 1 views
3

이런 식으로 말해줘.Java에서 캡슐화 된 스레드 안전 데이터 구조에 대한 액세스를 동기화해야합니까?

class QueBean extends JPanel { 
    private Queue queue = new LinkedBlockingQueue(); 

    public Object poll(){ 
     return queue.poll(); 
    } 
} 
class QueBean extends JPanel { 
    private Queue queue = new LinkedBlockingQueue(); 

    public Object poll(){ 
     return queue.poll(); 
    } 
} 

class ConsumerBean extends JPanel implements Runnable{ 
    private QueBean queBean; 

    public synchronized run(){ 
     while (true) { 
      Object result = queBean.poll(); 
      if (result != null) { 
       jResultTextField.setText("got one"); 
      } 
      wait(500); 
     } 
    } 
} 

poll()QueBean이되어야 하는가?

+0

'queBean'을 어떻게 사용합니까? 예를 들어 무엇이 추가 되었습니까? –

+0

@ T.J. Crowder queBean은 임의로 큐에 항목을 추가하는 자체 스레드를 가지고 있습니다. – blank

답변

2

이 경우에는 외부 동기화가 필요하지 않습니다. BlockingQueue 계약서를 읽어보십시오.

BlockingQueue 구현은 스레드 안전성입니다. 모든 대기열 처리 방법 은 내부 잠금 또는 다른 형식의 동시성 제어를 사용하여 원자 적으로 효과를냅니다.

2

아니요. 필요가 없습니다. poll 메서드는 스레드로부터 안전한 메서드를 호출하는 것 외에는 아무 작업도 수행하지 않으므로 데이터가 손상 될 가능성이 없습니다.

1

queueQueBean에서 변경되지 않는 한이 작업을 수행 할 필요가 없습니다.

또한 약간의 속도 제한을 구현하지 않는 한 코드에 wait(500)이 필요하지 않습니다. 대기열이 차단되어 불필요합니다.

+0

나는 약간의 속도 제한을하고있다;) – blank

6

스레드 문제가 있지만 생각한 것이 아닙니다. 게시 한 코드는 거의 불법이며 결국 잠길 것입니다.

스윙의 핵심 규칙 중 하나는 하나의 스레드 만 "실현 된"구성 요소를 만질 수 있다는 것입니다. (현실화 란 화면 상 또는 "거의"화면 상에 있음을 의미합니다.)

이 : - 당신은 단지 그것을 할 수 없습니다

jResultTextField.setText("got one"); 

스레드 내부 잘못 될 확신합니다. invokeLater 또는 invokeAndWait를 확인하여 화면 업데이트를 AWT 스레드로 가져 오십시오.

그런데 구성 요소를 확장하는 모든 것에 스레드가있는 것이 재미 있습니다. 즉, 충돌이 발생한 곳을 즉각적으로 검색 할 수는 있지만, 오랫동안 Java 프로그래머가 한눈에 불안해해야합니다. - 클래스를 나눠서 GUI (컨트롤러)를 구동하는 부분을 GUI (뷰)에서 완전히 분리하는 것이 좋습니다 ..

+0

불법적 인 의미는 무엇입니까? 확실히 컴파일되고 실행됩니다. (textField 메소드 호출은 다른 private 메소드에있다) – blank

+2

'java.awt.EventQueue.invokeLater'가 당신이 원하는 것이다. –

+0

그래서 EventQueue에서 GUI 업데이트를 실행하면 더 안전할까요? – blank