Runs this execution list, executing all existing pairs in the order they were added. However, note that listeners added after this point may be executed before those previously added, and note that the execution order of all listeners is ultimately chosen by the implementations of the supplied execu
()
| 107 | |
| 108 | |
| 109 | public void execute() { |
| 110 | // Lock while we update our state so the add method above will finish adding any listeners |
| 111 | // before we start to run them. |
| 112 | RunnableExecutorPair list; |
| 113 | synchronized (this) { |
| 114 | if (executed) { |
| 115 | return; |
| 116 | } |
| 117 | executed = true; |
| 118 | list = runnables; |
| 119 | runnables = null; // allow GC to free listeners even if this stays around for a while. |
| 120 | } |
| 121 | // If we succeeded then list holds all the runnables we to execute. The pairs in the stack are |
| 122 | // in the opposite order from how they were added so we need to reverse the list to fulfill our |
| 123 | // contract. |
| 124 | // This is somewhat annoying, but turns out to be very fast in practice. Alternatively, we could |
| 125 | // drop the contract on the method that enforces this queue like behavior since depending on it |
| 126 | // is likely to be a bug anyway. |
| 127 | |
| 128 | // N.B. All writes to the list and the next pointers must have happened before the above |
| 129 | // synchronized block, so we can iterate the list without the lock held here. |
| 130 | RunnableExecutorPair reversedList = null; |
| 131 | while (list != null) { |
| 132 | RunnableExecutorPair tmp = list; |
| 133 | list = list.next; |
| 134 | tmp.next = reversedList; |
| 135 | reversedList = tmp; |
| 136 | } |
| 137 | |
| 138 | while (reversedList != null) { |
| 139 | executeListener(reversedList.runnable, reversedList.executor); |
| 140 | reversedList = reversedList.next; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | /** |
| 145 | * Submits the given runnable to the given {@link Executor} catching and logging all {@linkplain |
no test coverage detected