Represents the result of an asynchronous operation. @param The type of the result of the task.
| 26 | * The type of the result of the task. |
| 27 | */ |
| 28 | public class Task<TResult> { |
| 29 | private static final ExecutorService backgroundExecutor = Executors.newCachedThreadPool(); |
| 30 | /** |
| 31 | * An executor that runs a runnable inline (rather than scheduling it on a thread pool) as long as |
| 32 | * the recursion depth is less than MAX_DEPTH. If the executor has recursed too deeply, it will |
| 33 | * instead delegate to the backgroundExecutor in order to trim the stack. |
| 34 | */ |
| 35 | private static final Executor immediateExecutor = new Executor() { |
| 36 | private static final int MAX_DEPTH = 15; |
| 37 | private ThreadLocal<Integer> executionDepth = new ThreadLocal<Integer>(); |
| 38 | |
| 39 | /** |
| 40 | * Increments the depth. |
| 41 | * |
| 42 | * @return the new depth value. |
| 43 | */ |
| 44 | private int incrementDepth() { |
| 45 | Integer oldDepth = executionDepth.get(); |
| 46 | if (oldDepth == null) { |
| 47 | oldDepth = 0; |
| 48 | } |
| 49 | int newDepth = oldDepth.intValue() + 1; |
| 50 | executionDepth.set(newDepth); |
| 51 | return newDepth; |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Decrements the depth. |
| 56 | * |
| 57 | * @return the new depth value. |
| 58 | */ |
| 59 | private int decrementDepth() { |
| 60 | Integer oldDepth = executionDepth.get(); |
| 61 | if (oldDepth == null) { |
| 62 | oldDepth = 0; |
| 63 | } |
| 64 | int newDepth = oldDepth.intValue() - 1; |
| 65 | if (newDepth == 0) { |
| 66 | executionDepth.remove(); |
| 67 | } else { |
| 68 | executionDepth.set(newDepth); |
| 69 | } |
| 70 | return newDepth; |
| 71 | } |
| 72 | |
| 73 | public void execute(Runnable command) { |
| 74 | int depth = incrementDepth(); |
| 75 | try { |
| 76 | if (depth <= MAX_DEPTH) { |
| 77 | command.run(); |
| 78 | } else { |
| 79 | backgroundExecutor.execute(command); |
| 80 | } |
| 81 | } finally { |
| 82 | decrementDepth(); |
| 83 | } |
| 84 | } |
| 85 | }; |
nothing calls this directly
no outgoing calls
no test coverage detected