ExecutorService - pojedyńczy wątek a wiele akcji

0

mam zdefiniowane
@Service a w nim
private final ExecutorService executor = Executors.newSingleThreadExecutor();

Wykonanie akcji po stronie serwisu trwa ok 1 min. A Requesty wywołujące ten serwis przychodzą częściej tzn. kilkanaście na minutę.

Wątek jeśli jest wolny wykonuję pracę po stronie serwisu, a co się dzieje z pozostałymi requestami? One się kolejkują? Jeśli tak to jak zdefiniowac kolejkę?

3

Pod spodem masz LinkedBlockingQueue. Jeśli chcesz zdefiniować własną to możesz to zrobić w takim sam sposób jak robi to metoda Executors.newSingleThreadExecutor();

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

Warto mieć na uwadze, że domyślny rozmiar kolejki to Integer.MAX_VALUE.

0

@Service a w nim
private final ExecutorService executor = Executors.newSingleThreadExecutor();

Jeżeli usługa jest singletonem (a tak będzie w Springu) to niestety masz jeden wątek i wiele zadań. Zadania się skolejkują co jest ładnie opisane w java docu:

Creates an Executor that uses a single worker thread operating off an unbounded queue.

Czyli kolejka zadań do wykonania może rosnąć w nieskończoność.

Osobiście radzę mieć albo fixed thread size executor + możliwość zmiany liczby wątków w runtime'ie lub caching executor z rozsądnym maxem na liczbę wątków (trzeba zobaczyć czy te zadania to IO czy CPU itp.).

To co się dokładnie stanie zależy od tego czy czekasz na wynik tego zadania wrzuconego na executor. Jeżeli nie to po prostu kolejka będzie rosnąć, w przypadku restartu aplikacji stracisz pewne dane. Jeżeli czekasz to obawiam się że przy takich czasach wykonania, przy 10 requestach / min będziesz miał timeouty na połączeniu HTTP po stronie serwera i klienta.

0

Wygląda to tak, że odpowiedź jest od razu zwracana:

 private final ExecutorService executor = Executors.newSingleThreadExecutor();

public void submitXYZ(XYZData XYZData) {
        executor.submit(() -> {
            processXYZ(XYZData);
        });
    }

    public void submitXYZStatus(String requestRef, String requestStatus, String reasonComment) {
        executor.submit(() -> {
            sendXYZStatus(requestRef, requestStatus, reasonComment);
        });
    }

    private void processXYZ(XYZData XYZData) {
        XYZResponse XYZResponse = abc(XYZData);
        if (XYZResponse.getResult().equals(ResponseEnum.DONE)) {
            XYZStatus.sendXYZStatus(XYZData.getRequestRef(), ResponseEnum.DONE.name(), null);
        } else {
            XYZStatus.sendXYZStatus(XYZData.getRequestRef(), XYZResponse.getResult().name(),
                    XYZResponse.getErrorMessage());
        }
    }

    private String sendXYZStatus(String requestRef, String requestStatus, String reasonComment) {
        return XYZStatus.sendXYZStatus(requestRef, requestStatus, reasonComment);
    }

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