1 /***
2 * Copyright 2009 Martin Vysny.
3 *
4 * This file is part of WebVM.
5 *
6 * WebVM is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * WebVM is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WebVM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 package sk.baka.webvm.misc;
20
21 import java.util.concurrent.Executors;
22 import java.util.concurrent.ScheduledExecutorService;
23 import java.util.concurrent.ScheduledThreadPoolExecutor;
24 import java.util.concurrent.ThreadFactory;
25 import java.util.concurrent.atomic.AtomicInteger;
26
27 /***
28 * Executes various tasks in background thread.
29 * @author Martin Vysny
30 */
31 public abstract class BackgroundService {
32 /***
33 * A short name of the service - used in thread names.
34 */
35 protected final String name;
36 /***
37 * Maximum thread pool size.
38 */
39 protected final int maxThreads;
40
41 /***
42 * Creates new service instance.
43 * @param name A short name of the service - used in thread names.
44 * @param maxThreads Maximum thread pool size.
45 */
46 protected BackgroundService(final String name, final int maxThreads) {
47 this.name = name;
48 this.maxThreads = maxThreads;
49 }
50
51 /***
52 * Starts the sampling process in a background thread.
53 */
54 public synchronized void start() {
55 if (executor != null) {
56 throw new IllegalStateException("Already started.");
57 }
58 executor = new ScheduledThreadPoolExecutor(1, newDaemonFactory(name));
59 started(executor);
60 }
61 private ScheduledExecutorService executor = null;
62
63 /***
64 * Invoked when the service is started.
65 * @param executor executes tasks.
66 */
67 protected abstract void started(final ScheduledExecutorService executor);
68
69 /***
70 * Returns the executor.
71 * @return the executor. null if not started.
72 */
73 protected synchronized final ScheduledExecutorService getExecutor() {
74 return executor;
75 }
76
77 /***
78 * Disposes of this sampler. This instance is no longer usable and cannot be started again.
79 */
80 public final synchronized void stop() {
81 if (executor != null) {
82 executor.shutdownNow();
83 executor = null;
84 stopped();
85 }
86 }
87
88 /***
89 * Invoked after the service has been stopped.
90 */
91 protected abstract void stopped();
92
93 /***
94 * Creates a new factory which creates daemon threads using the {@link Executors#defaultThreadFactory()}.
95 * @param name create threads marked with this name.
96 * @return a daemon thread factory.
97 */
98 public static ThreadFactory newDaemonFactory(final String name) {
99 return new ThreadFactory() {
100
101 private final ThreadFactory def = Executors.defaultThreadFactory();
102 private final AtomicInteger threadNum = new AtomicInteger(0);
103
104 public Thread newThread(Runnable r) {
105 final Thread result = def.newThread(r);
106 result.setName("WebVM: " + name + "-" + threadNum.incrementAndGet());
107 result.setDaemon(true);
108 return result;
109 }
110 };
111 }
112 }