Remove most of atomix.utils.*
[controller.git] / third-party / atomix / utils / src / main / java / io / atomix / utils / concurrent / OrderedExecutor.java
1 /*
2  * Copyright 2017-present Open Networking Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package io.atomix.utils.concurrent;
17
18 import java.util.LinkedList;
19 import java.util.concurrent.Executor;
20
21 /**
22  * Executor that executes tasks in order on a shared thread pool.
23  * <p>
24  * The ordered executor behaves semantically like a single-threaded executor, but multiplexes tasks on a shared thread
25  * pool, ensuring blocked threads in the shared thread pool don't block individual ordered executors.
26  */
27 public class OrderedExecutor implements Executor {
28   private final Executor parent;
29   private final LinkedList<Runnable> tasks = new LinkedList<>();
30   private boolean running;
31
32   public OrderedExecutor(Executor parent) {
33     this.parent = parent;
34   }
35
36   private void run() {
37     for (;;) {
38       final Runnable task;
39       synchronized (tasks) {
40         task = tasks.poll();
41         if (task == null) {
42           running = false;
43           return;
44         }
45       }
46       task.run();
47     }
48   }
49
50   @Override
51   public void execute(Runnable command) {
52     synchronized (tasks) {
53       tasks.add(command);
54       if (!running) {
55         running = true;
56         parent.execute(this::run);
57       }
58     }
59   }
60 }