OrderedExecutor

2906 단어
JAVA Executor와의 차이점
vertx 프레임워크는 OrderedExecutor의 실현을 제공합니다. 제출한 작업이 엄격한 제출 순서에 따라 실행되는 것을 보장합니다. idk Executor의 스레드 탱크에서 다중 스레드 상황에서 제출한 작업의 순서를 보장할 수 없습니다.
원본 코드 분석
다음은vertx의OrderedExecutor 구현을 보십시오. 원본 코드가 길지 않습니다. 아래와 같습니다.
private static final class OrderedExecutor implements Executor {
    private final LinkedList tasks = new LinkedList<>();
    private boolean running;
    private final Executor parent;
    private final Runnable runner;
    public OrderedExecutor(Executor parent) {
        this.parent = parent;
        runner = () -> {
            for (; ; ) {
                final Runnable task;
                synchronized (tasks) {
                      task = tasks.poll();
                      if (task == null) {
                        running = false;
                        return;
                      }
                }
                try {
                      task.run();
                } catch (Throwable t) {
                      log.error("Caught unexpected Throwable", t);
                }
            }
        };
    }

    public void execute(Runnable command) {
        synchronized (tasks) {
            tasks.add(command);
            if (!running) {
                running = true;
                parent.execute(runner);
            }
        }
    }
}  

OrderedExecutor는 4개의 구성원 변수를 포함하고tasks(LinkedList)는runnable 대기열이며,parent(Executor)는runnable를 실제로 실행하는 실행기,runner(Runnable)는 순서 실행기가 실행할 작업이며,running은 실행 상태 표시이다.
우선runner를 분석합니다. 실행 중인 작업은 순환 작업입니다.tasks에서 실행할 작업이 없으면 종료합니다.그 논리는 간단하다. 바로tasks에서 임무를 가져오고 실행하는 것이다.
다시 excute 방법을 보면 논리도 간단합니다.tasks에runnable를 추가하고,runner가 실행하지 않으면parent 스레드 탱크에 제출하여 실행합니다.
runner는tasks에서 순서대로 작업을 수행하기 때문에 OrderedExecutor execute의 작업이 순서대로 실행될 것을 보장합니다.
다음은 OrderedExecutor를 만드는 공장 클래스 OrderedExecutorFactory의 코드입니다.
public class OrderedExecutorFactory {

    static final Logger log = LoggerFactory.getLogger(OrderedExecutorFactory.class);

    private final Executor parent;

    public OrderedExecutorFactory(Executor parent) {
        this.parent = parent;
    }

    public OrderedExecutor getExecutor() {
        return new OrderedExecutor(parent);
    }
}

그 코드는 더 간단합니다. 루틴 실행기parent에 전송됩니다. OrderedExecutor를 만들 때마다 이parent 실행기를 공유해야 합니다.
다음은 OrderedExecutor와 Executor의 관계를 분석해 보겠습니다. OrderedExecutor는 Executor를 실현했지만 단순한 평행 대등 관계가 아닙니다. 1개의 Executor는 여러 개의 OrderedExecutor에 대응할 수 있습니다.
1개의 Executor는 1개의 스레드 탱크에 해당하지만, 각각의 OrderedExecutor는 실행 상태에서 1개의 스레드를 독점합니다. 왜냐하면,runner를parent에 제출할 때,parent는 1개의 빈 스레드를 선택하여 이 스레드를 실행합니다. 이 스레드는 순환 작업이고, 이 스레드를 독점합니다.
OrderedExecutor는 1개의 러너 퀘스트를 통해 이 OrderedExecutor에 제출된runnable를 처리하고tasks의 모든 퀘스트를 처리한 후 루틴을parent(Executor)에 반환합니다. 다음에 새로운runnable가 제출될 때 러너를parent(Executor)에 제출하고parent는 빈 루틴 1개를 꺼내서 러너를 실행합니다. 이 러너는 이 루틴을 독점합니다.

좋은 웹페이지 즐겨찾기