Nice programing

ArrayList를 스레드로부터 안전하게 만드는 방법은 무엇입니까?

nicepro 2020. 10. 4. 13:22
반응형

ArrayList를 스레드로부터 안전하게 만드는 방법은 무엇입니까? 자바 문제에 대한 또 다른 접근 방식?


실행이 완료되는 즉시 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.


당신은 수있는 잘못된 방법을 사용합니다. 자동차를 시뮬레이션하는 스레드 하나가 다른 자동차 시뮬레이션 스레드보다 먼저 완료된다고해서 첫 번째 스레드가 시뮬레이션 된 레이스에서 승리해야한다는 의미는 아닙니다.

It depends a lot on your application, but it might be better to have one thread that computes the state of all cars at small time intervals until the race is complete. Or, if you prefer to use multiple threads, you might have each car record the "simulated" time it took to complete the race, and choose the winner as the one with shortest time.


You can also use synchronized keyword for addFinisher method like this

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

So you can use ArrayList add method thread-safe with this way.


Whenever you want to use ant thread safe version of ant collection object,take help of java.util.concurrent.* package. It has almost all concurrent version of unsynchronized collection objects. eg: for ArrayList, you have java.util.concurrent.CopyOnWriteArrayList

You can do Collections.synchronizedCollection(any collection object),but remember this classical synchr. technique is expensive and comes with performence overhead. java.util.concurrent.* package is less expensive and manage the performance in better way by using mechanisms like

copy-on-write,compare-and-swap,Lock,snapshot iterators,etc.

So,Prefer something from java.util.concurrent.* package


You can change from ArrayList to Vector type, in which every method is synchronized.

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

You can also use as Vector instead, as vectors are thread safe and arraylist are not. Though vectors are old but they can solve your purpose easily.

But you can make your Arraylist synchronized like code given this:

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

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

반응형