1 package com.atlassian.plugin.osgi.spring;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import org.springframework.core.task.AsyncTaskExecutor;
6
7 import java.util.concurrent.Callable;
8 import java.util.concurrent.ExecutorService;
9 import java.util.concurrent.Executors;
10 import java.util.concurrent.Future;
11 import java.util.concurrent.ThreadFactory;
12 import java.util.concurrent.TimeUnit;
13 import java.util.concurrent.atomic.AtomicInteger;
14
15
16
17
18
19
20
21 public class ThreadPoolAsyncTaskExecutor implements AsyncTaskExecutor {
22 private static final Logger log = LoggerFactory.getLogger(ThreadPoolAsyncTaskExecutor.class);
23
24 private final ExecutorService executor = Executors.newCachedThreadPool(new NamedThreadFactory());
25
26
27
28
29
30
31
32 @Override
33 public void execute(Runnable task, long startTimeout) {
34
35 executor.execute(task);
36 }
37
38 @Override
39 public Future<?> submit(Runnable task) {
40 return executor.submit(task);
41 }
42
43 @Override
44 public <T> Future<T> submit(Callable<T> task) {
45 return executor.submit(task);
46 }
47
48
49
50
51
52
53 @Override
54 public void execute(Runnable task) {
55 this.execute(task, -1);
56 }
57
58
59
60
61
62 public void shutdown() {
63 log.debug("Attempting to shutdown ExecutorService");
64
65 executor.shutdown();
66 try {
67 if (executor.awaitTermination(5, TimeUnit.SECONDS)) {
68 log.debug("ExecutorService has shutdown gracefully");
69 } else {
70
71
72 log.warn("ExecutorService did not shutdown within the timeout; forcing shutdown");
73
74 executor.shutdownNow();
75 if (executor.awaitTermination(5, TimeUnit.SECONDS)) {
76
77 log.debug("ExecutorService has been forced to shutdown");
78 } else {
79
80
81
82 log.warn("ExecutorService did not shutdown; it will be abandoned");
83 }
84 }
85 } catch (InterruptedException e) {
86 log.warn("Interrupted while waiting for the executor service to shutdown; some worker threads may " +
87 "still be running");
88 Thread.currentThread().interrupt();
89 }
90 }
91
92
93
94
95 private static class NamedThreadFactory implements ThreadFactory {
96 private final AtomicInteger counter = new AtomicInteger();
97
98 @Override
99 public Thread newThread(Runnable r) {
100 Thread thread = new Thread(r);
101 thread.setDaemon(false);
102 thread.setName("ThreadPoolAsyncTaskExecutor::Thread " + counter.incrementAndGet());
103 return thread;
104 }
105 }
106 }