ArrayBlockingQueue zbieranie danych

0

Pisze program korzystając z wzorca producer worker i nie bardzo wiem jak wyciągać z kolejki dane które tam wrzucam. Oczywiście nadaje każdemu rządaniu unikalne id, ale jedyny sposób na uzyskanie tych samych danych z powrotem jaki mi przyhodzi do głowy to pętla while(listIn.size() != listOut.size()) lecz wiem, że to rozwiązanie niesie ze sobą wiele błędów i nie jest poprawne.

Klasa przechowująca referencje do kolejek:

public class Queue {

    private static final Integer QUEUE_SIZE = 1024;

    public static final BlockingQueue<Pair<String, String>> URL_QUEUE = new ArrayBlockingQueue<>(QUEUE_SIZE);
    public static final BlockingQueue<Pair<String, byte[]>> REQUEST_QUEUE = new ArrayBlockingQueue<>(QUEUE_SIZE);
    public static final BlockingQueue<Pair<String, String>> ANSWERS = new ArrayBlockingQueue<>(QUEUE_SIZE);
}

Metoda wstawiająca dane i zwracająca przekonwertowane:

    @Override
    public List<String> getBase64(List<String> urls) {
        String uniqueRequestID = UUID.randomUUID().toString();

        urls.parallelStream()
                .forEach(url -> {
                    try {
                        Queue.URL_QUEUE.put(new Pair<>(uniqueRequestID, url));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });

        List<String> base64 = new ArrayList<>(urls.size());
        while (base64.size() != urls.size()) {
            try {
                Pair<String, String> answer = Queue.ANSWERS.take();
                if (answer.getKey().equals(uniqueRequestID)) {
                    base64.add(answer.getValue());
                } else {
                    Queue.ANSWERS.put(answer);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return base64;
    }

Może zmiana kolejki przechowującej odpowiedzi na mape, a konkretnie concurrenthashmap jest dobrym pomysłem?

0

Może nie trzeba szukać odpowiedzi, tylko czekać aż sama wpadnie. Mieć wątek, który pobiera odpowiedzi i dalej je przetwarza. Po co mu szukać konkretnego id?

0

Ja nie chce tych odpowiedzi dalej przetwarzać, chce po prostu je zwrócić. Przykładowo dostaje rządzanie lista dziesięciu stringow url wrzucam to wszystko najpierw do kolejki 'URL_QUEUE' nadając temu odpowiednie id. Następnie producent przerabia dane i wstawia je do kolejk 'REQUEST_QUEUE' z której pobiera worker przerabia i wrzuca do 'ANSWERS'. No i moim problem jest to jak pobrać dane, bo dostając pare rządań z różnymi danymi one przerabiają się równolegle jedyne po czym mogę je rozróżnić to własnie id jakie nadje im na początku.

0

Skoro już wszedłeś w asynchroniczność, to requesty http też przetwarzaj asynchronicznie. Wtedy pozbędziesz się problemu. Przetwarzanie asynchroniczne http polega na tym, że zaraz po przekazaniu sprawy do kolejki wyskakujesz z funkcji http. Do kolejki natomiast przekazujesz jakąś referencję, która pozwala potem zwrócić wynik serwerowi http, który na to czeka.

1 użytkowników online, w tym zalogowanych: 0, gości: 1