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 {
23 private final ExecutorService executor = Executors.newCachedThreadPool(new NamedThreadFactory());
24
25
26
27
28
29
30 @Override
31 public void execute(Runnable task, long startTimeout)
32 {
33
34 executor.execute(task);
35 }
36
37 @Override
38 public Future<?> submit(Runnable task)
39 {
40 return executor.submit(task);
41 }
42
43 @Override
44 public <T> Future<T> submit(Callable<T> task)
45 {
46 return executor.submit(task);
47 }
48
49
50
51
52
53 @Override
54 public void execute(Runnable task)
55 {
56 this.execute(task, -1);
57 }
58
59
60
61
62
63 public void shutdown()
64 {
65 Logger log = LoggerFactory.getLogger(getClass());
66 log.debug("Attempting to shutdown ExecutorService");
67
68 executor.shutdown();
69 try
70 {
71 if (executor.awaitTermination(5, TimeUnit.SECONDS))
72 {
73 log.debug("ExecutorService has shutdown gracefully");
74 }
75 else
76 {
77
78
79 log.warn("ExecutorService did not shutdown within the timeout; forcing shutdown");
80
81 executor.shutdownNow();
82 if (executor.awaitTermination(5, TimeUnit.SECONDS))
83 {
84
85 log.debug("ExecutorService has been forced to shutdown");
86 }
87 else
88 {
89
90
91
92 log.warn("ExecutorService did not shutdown; it will be abandoned");
93 }
94 }
95 }
96 catch (InterruptedException e)
97 {
98 log.warn("Interrupted while waiting for the executor service to shutdown; some worker threads may " +
99 "still be running");
100 Thread.currentThread().interrupt();
101 }
102 }
103
104
105
106
107 private static class NamedThreadFactory implements ThreadFactory
108 {
109 private final AtomicInteger counter = new AtomicInteger();
110
111 @Override
112 public Thread newThread(Runnable r)
113 {
114 Thread thread = new Thread(r);
115 thread.setDaemon(false);
116 thread.setName("ThreadPoolAsyncTaskExecutor::Thread " + counter.incrementAndGet());
117 return thread;
118 }
119 }
120 }