2011-03-31 3 views
2

나는 (int i ...) 루프에 대한 구식을 사용하여 자바리스트를 반복하고 싶다. 왜냐하면 주어진 i와 루프 반복에 대해 i와 관련된 여러 요소에 접근하고 싶다. 그렇다면 (Object o : objects) for list iterator를 사용할 수 없습니다.자바 동기화에 대한 간단한 질문

내가 실행하는 동안 다른 코드가 목록에 액세스하지 못하게하려면 어떻게해야합니까? 경로 개체가 목록을 들고, 또한

synchronized(path){ 
    for (int i = 0; i < path.getPoints().size(); i++){ 
     ... 
    } 
} 

와도

synchronized(this){ 
    for (int i = 0; i < path.getPoints().size(); i++){ 
     ... 
    } 
} 

어디 "이"하고 싶은 렌더러입니다

나는

synchronized(path.getPoints()){ 
    for (int i = 0; i < path.getPoints().size(); i++){ 
     ... 
    } 
} 

시도 동기화 문제없이 경로를 제대로 렌더링합니다. 사전에

감사합니다,

마틴

+0

게시 한 동기화 코드는 세 가지 경우 모두 작동해야합니다. 동기화 가드 밖의 경로에 액세스하는 다른 스레드가없는 것이 확실합니까? – templatetypedef

+0

다른 스레드가 목록에 액세스하는 이유는 무엇입니까? – 3urdoch

+0

@ murdoch : 백그라운드에서 실행중인 편집기 스레드 하나와 UI 스레드 하나가 연속적으로 실행되고 점 목록을 렌더링했습니다. @template :이 두 스레드 중 하나만 동기화하는 중이었습니다 – Martin

답변

7

실행 중에 다른 코드 이 목록에 액세스 할 수 없도록하려면 어떻게해야합니까?

다른 모든 코드 이 동일한 개체에서 동기화되도록합니다. synchronized(path.getPoints())이 최선의 선택입니다. getPoints()Collections.synchronizedList()을 통해 래핑 된 목록을 반환하는 것이 좋습니다. 그러면 get() 또는 add() 호출을 명시 적으로 동기화 할 필요는 없지만 반복을 위해 동기화가 여전히 필요합니다.

복잡한가? 네. 이것이 공유 메모리 다중 스레드 프로그래밍이 매우 어려운 것으로 여겨지는 이유입니다.

+0

이 특정 질문에 synchronizedList를 사용하면 쓸모가 없습니다. 동일한 동기화 개체를 사용하여 모든 get, add 및 iteration을 동기화해야하기 때문입니다. 내 대답을보십시오 ... – nanda

+0

@ nanda : 실제로이 시나리오는 synchronizedDoc()에 대한 API 문서에서 올바른 사용법에 대한 예제로 설명됩니다. 분명히 래퍼는 외부 동기화가 작동하도록 동기화를 위해 자체를 사용합니다. –

+0

당신이 맞습니다 ... – nanda

0

당신은 동기화 path.getPoints을()하고 점 목록 (또는 어쩌면 배열)의 사본을 반환 할 수 있습니다. 그런 다음 반복 할 때 동기화 할 필요가 없습니다. 포인트가 비공개 인 경우 액세스하는 Path의 모든 메소드가 동기화되었는지 쉽게 확인할 수 있습니다.

0

"synchronized (this)"(여기서 "this"는 렌더러)는 다른 스레드가 동일한 렌더러를 동시에 실행할 수 없도록합니다. 그러나 다른 스레드는 목록 및 "경로"개체에 액세스 할 수 있습니다.

0

가장 좋은 방법은 (동일한 컬렉션의) 동기화 된 블록에서 쓰기를 위해 컬렉션 (path.getPoints())을 사용하는 것을 보장하는 것입니다. 그러면 소비자 (예 : 읽기 전용)가 열거자를 사용하려는 컬렉션은 컬렉션에서 동기화 된 블록을 사용하여 안전하게 수행 할 수 있습니다.

0

나는 이것을 쓸 것을 권하고 싶습니다.

List<Point> points = path.getPoints() 
synchronized(points){ 
    for (Point point: points){ 
     ... 
    } 
} 

이 다른 무언가를 반환하지 않습니다() getPoints를 확인하고 코드 이럴를 단순화합니다.

나는 또한의 @Michaels 제안을 사용하는 것 중 하나 getPoints()를 액세스하거나 만들 때마다 동기화 그것을 Collectons.synchronizedList() 또는 으로 CopyOnWriteArrayList()

주와 같은 스레드 안전 목록 : 당신이 사용하는 경우 스레드 안전 목록이면 동기화 할 필요가 없습니다.