programing

Array List 스레드 세이프 만드는 방법자바 문제에 대한 또 다른 접근법?

copysource 2022. 10. 2. 15:25
반응형

Array List 스레드 세이프 만드는 방법자바 문제에 대한 또 다른 접근법?

스레드 클래스를 확장하는 RaceCar 개체를 실행이 끝나는 대로 유지하는 데 사용할 ArrayList가 있습니다.Race라는 클래스는 RaceCar 객체가 실행이 완료되면 호출하는 콜백 메서드를 사용하여 이 ArrayList를 처리합니다.콜백 메서드 addFinisher(RaceCar finisher)는 RaceCar 개체를 ArrayList에 추가합니다.이것은 스레드의 실행이 종료되는 순서를 나타냅니다.

Array List가 동기화되어 있지 않기 때문에 스레드 세이프가 아닌 것을 알고 있습니다.컬렉션을 사용해 보았습니다.synchronized Collection(c Collection) 메서드를 사용하여 새 ArrayList를 전달하고 반환된 컬렉션을 ArrayList에 할당합니다.단, 이 경우 컴파일러 오류가 발생합니다.

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(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의 슈퍼타입이므로 지정해야 합니다.

그렇지 않으면, 네가 하는 일은 괜찮아 보여.다른 옵션은 동기화된 벡터를 사용할 수 있지만, 저는 아마 이렇게 할 것입니다.

CopyOnWriteArrayList

수업을 이용하다.의 스레드 세이프 버전입니다.

잘못된 접근 방식을 사용하고 있는 것 같습니다.자동차를 시뮬레이션하는 하나의 스레드가 다른 자동차 시뮬레이션 스레드보다 먼저 완료된다고 해서 첫 번째 스레드가 시뮬레이션 경주에서 우승해야 한다는 것을 의미하지는 않습니다.

어플리케이션에 따라 다르지만, 레이스가 완료될 때까지 작은 시간 간격으로 모든 차량의 상태를 계산하는 스레드가 하나 있는 것이 좋을지도 모릅니다.또는 여러 개의 스레드를 사용하는 것을 선호할 경우 각 차량이 레이스를 완주하는 데 걸린 "시뮬레이션된" 시간을 기록하고 가장 짧은 시간으로 우승자를 선택할 수 있습니다.

를 사용할 수도 있습니다.synchronized키워드addFinisher이런 방법

    //Implement the one method in the RaceListener interface
    public synchronized void addFinisher(RaceCar finisher) {
        finishingOrder.add(finisher);
    }

따라서 ArrayList add 메서드 스레드세이프를 이 방법으로 사용할 수 있습니다.

개미 수집 개체의 개미 스레드 세이프 버전을 사용하려면 항상 java.util.concurrent를 사용하십시오.* 패키지동기화되지 않은 수집 개체의 거의 모든 동시 버전이 있습니다.예: ArrayList의 경우 java.util.concurrent가 있습니다.Copy On Write Array List

수집을 할 수 있습니다.synchronized Collection(임의의 컬렉션 오브젝트) 단, 이 클래식 동기화는 잊지 마십시오.기술은 비용이 많이 들고 성능 오버헤드가 수반됩니다.java.discurrent.concurrent.* 패키지는 저렴하며 다음과 같은 메커니즘을 사용하여 성능을 보다 효율적으로 관리합니다.

copy-on-write, compare-and-swap, Lock, snapshot 반복기 등

java.util.concurrent에서 원하는 게 있어요* 패키지

벡터는 스레드 세이프이고 어레이 리스트는 그렇지 않기 때문에 대신 벡터로 사용할 수도 있습니다.벡터는 오래되었지만 당신의 목적을 쉽게 해결할 수 있습니다.

단, 다음과 같은 경우 Arraylist를 코드처럼 동기화할 수 있습니다.

Collections.synchronizedList(new ArrayList(numberOfRaceCars())); 

모든 메서드가 동기화되는 ArrayList에서 Vector 유형으로 변경할 수 있습니다.

private Vector finishingOrder;
//Make a Vector to hold RaceCar objects to determine winners
finishingOrder = new Vector(numberOfRaceCars);

언급URL : https://stackoverflow.com/questions/2444005/how-do-i-make-my-arraylist-thread-safe-another-approach-to-problem-in-java

반응형