문제

이것이 내 동기화하는 올바른 방법인지 확실하지 않습니다. ArrayList.

나는있다 ArrayList in_queue 그것은에서 전달됩니다 registerInQueue 기능.

ArrayList<Record> in_queue = null;

public void registerInQueue(ArrayList in_queue)
{
    this.in_queue = in_queue;
}

이제 동기화하려고합니다. 이것이 나의 시력을내는 것입니다 in_queue 객체가 올바르게?

List<Record> in_queue_list = Collections.synchronizedList(in_queue);

synchronized (in_queue_list) {
    while (in_queue_list.size() > 0) {
        in_queue_list.remove(0);
    }
}
도움이 되었습니까?

해결책

무의미하고 코드가 느려질 수있는 두 번 동기화하고 있습니다. 목록을 반복하면서 변경하면 전체 작업에 대해 동기화가 필요합니다. synchronized (in_queue_list) 사용 Collections.synchronizedList() 이 경우 불필요합니다 (개별 작업을 동기화하는 래퍼를 만듭니다).

그러나 목록을 완전히 비우기 때문에 첫 번째 요소의 반복적 인 제거는 최악의 최악의 방법입니다. 각 요소에 대한 시체는 다음 요소를 모두 복사해야하므로 O (n^2) 작동 - 끔찍하게 만들어야합니다. 더 큰 목록의 경우 느리게.

대신, 간단히 전화하십시오 clear() - 반복이 필요하지 않습니다.

편집하다:단일 메드 동기화가 필요한 경우 Collections.synchronizedList() 나중에 이것은 올바른 방법입니다.

List<Record> in_queue_list = Collections.synchronizedList(in_queue);
in_queue_list.clear(); // synchronized implicitly, 

그러나 대부분의 경우 단일 메드 동기화는 불충분합니다 (예 : 모든 반복 또는 값을 얻을 때 계산을 기반으로 계산하고 결과로 대체). 이 경우 어쨌든 수동 동기화를 사용해야하므로 Collections.synchronizedList() 쓸모없는 추가 오버 헤드입니다.

다른 팁

당신의 예를 살펴보면, 나는 생각합니다 ArrayBlockingqueue (또는 형제 자매)가 사용될 수 있습니다. 그들은 당신을 위해 동기화를 돌보고 있으므로 스레드는 추가 동기화 작업없이 큐에 쓸 수 있거나 엿보기/테이크 할 수 있습니다.

정확하고 문서화되었습니다.

http://java.sun.com/javase/6/docs/api/java/util/collections.html#synchronizedlist(java.util.list)

그러나 목록을 지우려면 전화하십시오 list.clear ().

예, 올바른 방법이지만, 큐가 비어 있지 않으면 제거가 허용되지 않는 한 모든 제거제가 안전하기를 원한다면 동기화 된 블록이 필요합니다. 내 생각에 안전한 대기열과 디키어 작업을 원하므로 동기화 된 블록을 제거 할 수 있습니다.

그러나 Java에는 다음과 같이 훨씬 고급 동시 대기열이 있습니다. 동시에 린드 큐

일반 목록 (ArrayList 클래스에서 구현)을 사용하여 동기화하겠습니다. 동기화리스트면 클래스에 표시됩니다. SynchronizedList 메소드 문자열의 새로운 배열 목록입니다. 이 메소드는 동기화 된 문자열 목록을 반환합니다. // 여기 SynchronizedArrayList 클래스입니다

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
* @email kumarmanoj.mtech@gmail.com
* 
*/
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
    public static void main(String[] args) {    
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());
        synchronizedList.add("Aditya");
        synchronizedList.add("Siddharth");
        synchronizedList.add("Manoj");
        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<String> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Synchronized Array List Items: " + iterator.next());
            }
        }    
    }
}

목록을 반복 할 때이 액세스는 동기화 목록 개체의 잠금을 고정하는 동기화 된 블록을 사용하여 여전히 수행됩니다. 일반적으로 동기화 된 컬렉션을 반복하는 것은 동기화 된 블록으로 수행해야합니다.

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