필자는 컬렉션을 보유하고 있으며 해당 요소에 많은 작업을 수행하기 위해 많은 스레드를 생성하려고합니다. 컬렉션의 각 요소는 한 번만 처리해야합니다. 나는 가능한 한 최소한의 동기화를 유지하고 싶은 다음 코드를 내놓았다 :다중 스레드 반복이 안전합니까?
//getting the iterator is actually more complicated in my specific case
final Iterator it = myCollection.terator();
Thread[] threads = new Thread[numThreads];
for(int i = 0; i < numThreads; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
Object obj = null;
while(true) {
synchronized (it) {
if(it.hasNext())
obj = it.next();
else
return;
}
//Do stuff with obj
}
}
});
threads[i].start();
}
for (Thread t : threads)
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
참고 : 어떤 스레드가 이제까지
'OBJ와 함께 물건을'동안 항목을 추가하거나 제거하여 컬렉션을 수정하지 않습니다이 코드는 사람들이 컬렉션 자체에서 동기화하는 경향이있는 곳에서 발견 된 예제와 완전히 다르며 Collection.synchronizedStuff..
을 사용하거나 전체 반복에 대해 동기화합니다. 내 연구 동안 나는 ThreadPoolExecutor
을 사용하여 구현 된 더 나은 대안을 찾았지 만 잠시 잊어 버리자 ...
위의 코드 1을 위의 코드는 안전합니까? 그렇지 않다면, 왜?
메모 1이 사실로 유지되는 한 괜찮을 것입니다. 집행자는 확실히 이런 식으로 갈 길입니다. – BevynQ
성능상의 이유로'synchronized' 블록을 작게 유지하려고한다면, (네이티브) 각 쓰레드를 생성하고 실행하는 동안 얼마나 많은 시간이 소요되는지, 그리고 제안 된대로 executor를 사용하는 것이 놀랄 것입니다. –
개념 코드가 정상적으로 보입니다. 잘 작동해야합니다. 반복자에 대한 액세스 (객체 검사 및 읽기 포함)가 동기화되므로 아무런 문제가 발생하지 않습니다. – xagyg