2012-08-26 5 views
0

나는 대답을 찾기 위해 열심히 노력했지만 무엇이 잘못되었는지 알지 못합니다. JAVA 스레드 사용법을 배우고 있습니다. 내가 우주 함 게임을하고있다. 나는 enemys를 만드는 한가지 방법을 가지고있다. (그 적들은 ArrayList에 추가된다. 나는이 ArrayList에서 죽은 적을 찾아 보는 또 다른 방법을 가지고있다. (죽은 부울은 화면의 적을 죽이거나 그 죽임을 당하면 참이된다.) 만약 죽은 것이라면 ArrayList의 원소를 제거한다. 더 이상 칠해질 수 없다.) createEnemy 메서드를 사용하는 스레드가 하나 있는데 (잘 작동합니다). 문제는 지금,이 ereaseEnemy 메서드를 사용해야하지만 그것은 나와 동시성 오류를 제공해야합니다, 나는 두 가지 방법으로 동기화를 사용하여 시도했지만 ereaseEnemy 메서드는 결코 작동하지 않습니다. 이 문제를 어떻게 해결해야할지 모르겠다. 나는 다른 스레드를 만들기 위해 첫 번째 스레드 (작성자)를 멈 춥니 다? 나 여기 somethig가 없어? 감사! 적ArrayList의 Java 동시성

for (Enemigo enemigo1 : enemigos) { 
    if (!enemigo1.isEstaVivo()) { enemigos.remove(enemigo1); } 
} 
+4

아마 여러 스레드를 사용해서는 안됩니다. – SLaks

+1

arraylist에서 항목을 제거하는 방법에 대한 예제 코드는 무엇입니까? – kosa

+0

괜찮아요, 작동하지만, 어쨌든 어떻게 사용하지 않는지에 대한 단서가 없습니다. 창조자 스레드를 사용해야하는 것이야말로 적을 계속해서 보낼 수있는 유일한 방법입니다. 하지만 내가 말했듯이 어떻게 그 적의 명단을 청소할 수 있는지 모르겠다. 내가 그 목록을하지 않으면 성장과 성장을 계속하십시오. 어떤 충고? – MBRebaque

답변

0

을 제거

코드 당신은 스레드를 직접 동기화하려고해서는 안된다. Java가 java.util.concurrent 클래스를 사용하여이를 수행하게하십시오. 귀하의 경우 일정한 액세스 시간에 대해서는 ConcurrentLinkedQueue 또는 ConcurrentMap을 볼 것입니다. 선박 ID를지도의 키로 사용할 수 있습니다.

적군의 dead 깃발을 설정하여 여러 스레드가 올바르게 액세스 할 수 있도록해야합니다. 데이터 저장소는 그렇게하지 않을 것이며 모든 스레드에 대해 일관된 데이터 저장소 상태를 유지할 것입니다.

http://docs.oracle.com/javase/6/docs/api/index.html?java/util/concurrent/package-summary.html

+0

을 사용하십시오. 전체적으로 살펴 보겠습니다. thaks, 내가 그것을 고쳤는지 아닌지를 알기 위해 되돌아 갈 것입니다. – MBRebaque

5

당신은 정말 문제가되는 코드를 게시해야하지만, 나는 추측을 할 수 있습니다 : 당신이 ArrayList을 통해 당신이 list.remove(o)를 호출하는 루프 내에서 반복된다. throw 된 예외는 ConcurrentModificationException입니다. 반복하는 동안 List.remove() 메서드 중 하나를 호출 할 수 없습니다. Iterator.remove()을 사용해야합니다. 따라서이 유스 케이스에서 향상된 for 루프를 사용할 수 없다. (삭제하기 전에

for (Iterator<Enemigo> iter = enemigos.iterator(); iter.hasNext();) 
    if (!iter.next().isEstaVivo()) iterator.remove(); 
+0

나는 일종의 용의자입니다. 나는 그가 remove (index)를 호출하고 있다고 생각한다. – kosa

+0

@ Nambari 그는'remove (index)'를 사용하지 않습니다 – oldrinb

+0

@veer : enemigos.remove (enemigo1); 나는 enemigos가 목록이라고 가정하고 enemigos.remove (enemigo1)를 호출합니다. 색인에 따라 제거하십시오. 안 그래? – kosa

0

두 possibles 솔루션

1

) 목록의 복사본을 만드는 코드를 변경 크기가 너무 큰 경우) 성능 문제의 인식

ArrayList<enemigo> enemigosCopy= new ArrayList<enemigo>(); 
enemigosCopy.addAll(enemigos); 
//Do your deleting thing on enemigosCopy 

2) 반복자 사용

Iterator i =enemigos.iterator(); 
while (i.hasNext()) { 
    enemigo o = i.next(); 
    if (!enemigo1.isEstaVivo()) {  
    i.remove(o);  
    }    
} 
+0

왜 삭제합니까? 그는 ** 추가해야 할 각 요소를 확인하여 ** 새 목록을 작성해야합니다 **. –

+0

괜찮지 만, 나는 그걸로 의심 스럽다. 내가 할 일은 copyList의 적 형태 다.하지만 여전히 나는 할 것인가? (예 : 그들 모두와 함께 원래의 목록을 가지고 있습니까? – MBRebaque

+0

예, 원본은 변경되지 않습니다. 재 구축 접근법이 실제로 더 효과적 일 수 있습니다. 'ArrayList.remove'는 실제로해야 할 일에 대해 생각할 때 정말 끌기입니다. –