실행이 완료되는 즉시 Thread 클래스를 확장하는 RaceCar 개체를 유지하는 데 사용하려는 ArrayList가 있습니다. Race라고하는 클래스는 RaceCar 객체가 실행이 끝나면 호출하는 콜백 메서드를 사용하여이 ArrayList를 처리합니다. 콜백 메서드 인 addFinisher (RaceCar finisher)는 RaceCar 객체를 ArrayList에 추가합니다. 이것은 스레드가 실행을 완료하는 순서를 제공합니다.
ArrayList가 동기화되지 않았으므로 스레드로부터 안전하지 않습니다. 새 ArrayList를 전달하고 반환 된 Collection을 ArrayList에 할당하여 Collections.synchronizedCollection (c Collection) 메서드를 사용해 보았습니다. 그러나 이것은 나에게 컴파일러 오류를 제공합니다.
Race.java:41: incompatible types
found : java.util.Collection
required: java.util.ArrayList
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));
다음은 관련 코드입니다.
public class Race implements RaceListener {
private Thread[] racers;
private ArrayList finishingOrder;
//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));
//Fill array with RaceCar objects
for(int i=0; i<numberOfRaceCars; i++) {
racers[i] = new RaceCar(laps, inputs[i]);
//Add this as a RaceListener to each RaceCar
((RaceCar) racers[i]).addRaceListener(this);
}
//Implement the one method in the RaceListener interface
public void addFinisher(RaceCar finisher) {
finishingOrder.add(finisher);
}
내가 알아야 할 것은 올바른 접근 방식을 사용하고 있는지, 그렇지 않은 경우 코드를 스레드로부터 안전하게 만들기 위해 무엇을 사용해야합니까? 도와 주셔서 감사합니다!
답변
사용 Collections.synchronizedList()
.
전의:
Collections.synchronizedList(new ArrayList<YourClassNameHere>())
답변
변화
private ArrayList finishingOrder;
//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars)
…에
private List finishingOrder;
//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedList(new ArrayList(numberOfRaceCars)
List는 ArrayList의 상위 유형이므로이를 지정해야합니다.
그렇지 않으면 당신이하고있는 일이 괜찮아 보입니다. 다른 옵션은 동기화 된 Vector를 사용할 수 있다는 것입니다.하지만 이것이 아마도 제가 할 일입니다.
답변
CopyOnWriteArrayList
CopyOnWriteArrayList
수업을 사용하십시오 . 이것은의 스레드로부터 안전한 버전입니다 ArrayList
.
답변
당신은 수있는 잘못된 방법을 사용합니다. 자동차를 시뮬레이션하는 스레드 하나가 다른 자동차 시뮬레이션 스레드보다 먼저 완료된다고해서 첫 번째 스레드가 시뮬레이션 된 레이스에서 승리해야한다는 의미는 아닙니다.
애플리케이션에 따라 많이 다르지만 레이스가 완료 될 때까지 작은 시간 간격으로 모든 자동차의 상태를 계산하는 하나의 스레드를 갖는 것이 더 나을 수 있습니다. 또는 여러 스레드를 사용하는 것을 선호하는 경우 각 자동차가 레이스를 완료하는 데 걸린 “시뮬레이션 된”시간을 기록하고 가장 짧은 시간에 승자를 선택하도록 할 수 있습니다.
답변
이와 같은 방법으로 synchronized
키워드를 사용할 수도 있습니다.addFinisher
//Implement the one method in the RaceListener interface
public synchronized void addFinisher(RaceCar finisher) {
finishingOrder.add(finisher);
}
따라서이 방법으로 ArrayList add 메서드를 스레드로부터 안전하게 사용할 수 있습니다.
답변
ant 컬렉션 객체의 ant thread safe 버전을 사용하려면 java.util.concurrent. * 패키지의 도움을 받으십시오 . 동기화되지 않은 컬렉션 개체의 거의 모든 동시 버전이 있습니다. 예 : ArrayList의 경우 java.util.concurrent.CopyOnWriteArrayList가 있습니다.
Collections.synchronizedCollection (모든 컬렉션 객체)을 수행 할 수 있지만이 고전적인 동기화를 기억하십시오. 기술은 비싸고 성능 오버 헤드가 있습니다. java.util.concurrent. * 패키지는 저렴하며 다음과 같은 메커니즘을 사용하여 더 나은 방식으로 성능을 관리합니다.
쓰기시 복사, 비교 및 교체, 잠금, 스냅 샷 반복기 등
그래서, java.util.concurrent. * 패키지에서 무언가를 선호하십시오
답변
벡터는 스레드로부터 안전하고 arraylist는 그렇지 않으므로 대신 Vector로 사용할 수도 있습니다. 벡터는 오래되었지만 목적을 쉽게 해결할 수 있습니다.
그러나 다음과 같은 코드처럼 Arraylist를 동기화 할 수 있습니다.
Collections.synchronizedList(new ArrayList(numberOfRaceCars()));