View Javadoc

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 }