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

StackOverflow https://stackoverflow.com/questions/2239200

  •  19-09-2019
  •  | 
  •  

문제

이런 말이 있다고 말해서 (그리고 나는)

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 ~이다 synchronized 아니면 아니야?

도움이 되었습니까?

해결책

이 경우 외부 동기화가 필요하지 않습니다. 읽기 BlockingQueue 계약:

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

다른 팁

스레딩 문제가 있지만, 당신이 생각하는 문제는 아닙니다. 게시 한 코드는 거의 확실하지 않으며 결국 잠금됩니다.

스윙의 핵심 규칙 중 하나는 하나의 스레드 만 "실현 된"구성 요소를 터치 할 수 있다는 것입니다. (실현 된 화면 또는 "거의"화면에 실현).

이것:

jResultTextField.setText("got one"); 

스레드 내부는 틀렸을 것입니다. 당신은 그것을 할 수 없습니다. AWT 스레드에 화면 업데이트를 얻으려면 Invokelater 또는 InvokeAndwait를 확인하십시오.

그건 그렇고, 구성 요소를 확장하는 스레드를 갖는 것은 재미있는 느낌이 든다. 충돌이 어디에 있는지 즉시 찾아 내야하지만, 오랜 시간 동안 Java 프로그래머를 불안하게 만들어야한다. 수업을 나누고 GUI (view)에서 GUI (컨트롤러)를 구동하는 부분을 완전히 분리합니다.

아뇨. 필요가 없습니다. 당신이 이래 poll 메소드는 스레드 안전 메소드를 호출하는 것 외에는 아무것도하지 않으며 데이터 손상의 가능성은 없습니다.

당신은 이것을 할 필요가 없습니다. queue 변경되지 않습니다 QueBean.

또한, 당신이 어떤 종류의 사소한 속도를 구현하려고하지 않는 한, 당신은 필요하지 않습니다. wait(500) 코드에서. 대기열이 차단되어 불필요합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top