2011-10-13 2 views
3

전체 배열을 잠 그려면 다음과 같이 synchronized 키워드를 사용할 수 있습니다.어떻게 정수 배열의 단일 요소를 동기화?

int arr[]; 

synchronized void inc(int a, int b){ 
    arr[a]=arr[a]+b; 
} 

그러나 다른 스레드에서 배열의 다른 항목을 동일하게 동시에 읽을 수 있도록 arr[a] 항목 만 잠글 수 있습니까? 시각?

답변

3

하지 않습니다,하지만 당신은 별개의 객체와 배열을 당신의 int 배열과 같은 크기 인 객체 배열을 생성하고 채울 수 있습니다. 당신은 int 배열의 특정 요소에 잠글 그래서 때, 당신은 corresponsible 인덱스에서 해당 개체에 잠금 :

final Object[] locks = new Object[arr.length]: 
for(int i = 0; i < arr.length; i++) { 
locks[i] = new Object(); 
} 

하는 잠금 때이 정말 병 목 인 경우

synchronized(locks[a]) { 
    // do something here 
} 
1

아니요, 배열 요소는 프리미티브이며 사용자가 설정할 수 없습니다. (잠금은 변경 가능한 객체에만 도움이되기 때문에 객체 인 경우에도 도움이되지 않습니다. 해당 인덱스의 내용이 아닌 배열 인덱스를 잠그고 싶습니다.)

유일하게 가능한 것은 배열 색인을 고유하게 참조하고이를 동기화하거나 (Semaphore을 사용하는) 키를 생성하는 것이지만 다른 스레드가 동일한 방식으로 배열에 액세스하는 경우에만 도움이됩니다 .

디자인을 변경하고 int 배열을 제거한 다음 해당 요소 (ListCollections.synchronizedList()로 래핑 됨)에 대한 액세스를 동기화 할 수있는 데이터 구조를 사용하면 좋은 출발점이됩니다. 당신을 위해

6

어쩌면 더 적합한 구조는 아웃 - 오브 - 박스 AtomicIntegerArray

+0

아마도 이것은 가장 좋은 답변 일 것입니다. 그러나 Ray의 대답은 내가 특정 사례를 찾고있는 해결책입니다. – kooshka

0

을 당신을 위해 완전히 differnet 구조가 더 적절할 것 같습니다. 만약 당신이 8 코어라고한다면, 그들은 바쁜 시간과 1/8 정도의 시간 동안 심각한 도전을보기 위해 숫자를 더해야합니다. 이 작업을 수행하는 것이 작업의 1/8 정도라면 시스템을 잠그지 않도록 설계해야합니다.

여러 스레드에서 총 많은 값을 가져와야한다고 가정 해 봅시다. 예 : 숫자가 매우 긴 목록에 나타나는 횟수를 계산하십시오.

각 업데이트마다 실제적으로 값 비싼 잠금 장치가있는 카운터의 동기화 된 배열을 가질 수 있습니다. (SYnchronized는 빠르지 만 많이 추가하는 것보다 훨씬 느립니다.)

또는 모든 스레드가 자신의 합계를 유지하도록 할 수도 있습니다. 당신이 어떤 자물쇠도 사용하지 않았다는 것을 제외하면 최종 합계는 동일합니다!

관련 문제