]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/ExecutorWorker.java
Allow ExecutorWorker thread pool shutdown
[simantics/platform.git] / bundles / org.simantics.utils.thread / src / org / simantics / utils / threads / ExecutorWorker.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *     Semantum Oy - added shutdown facilities
12  *******************************************************************************/
13
14 package org.simantics.utils.threads;
15
16 import java.util.concurrent.Callable;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.ScheduledThreadPoolExecutor;
19 import java.util.concurrent.TimeUnit;
20 import java.util.concurrent.atomic.AtomicInteger;
21
22 /**
23  * @author Toni Kalajainen
24  * @author Tuukka Lehtonen
25  */
26 public class ExecutorWorker {
27
28         private static volatile ExecutorWorker instance;
29
30         public static ExecutorWorker getInstance() {
31                 if (instance == null) {
32                         synchronized (ExecutorWorker.class) {
33                                 if (instance == null)
34                                         instance = new ExecutorWorker();
35                         }
36                 }
37                 return instance;
38         }
39
40         private ExecutorWorker() {}
41
42         private final AtomicInteger counter = new AtomicInteger(0);
43         private final ThreadGroup threadGroup = new ThreadGroup("ExecutorWorker-Group");
44         private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1, r -> {
45                 Thread t = new Thread(threadGroup, r, "ExecutorWorker-" + (counter.incrementAndGet()));
46                 if (!t.isDaemon())
47                         t.setDaemon(true);
48                 if (t.getPriority() != Thread.NORM_PRIORITY)
49                         t.setPriority(Thread.NORM_PRIORITY);
50                 return t;
51         });
52
53         public synchronized ScheduledFuture<Object> timerExec(final Executable executable, int delay)
54         {
55                 Callable<Object> c = () -> {
56                         ThreadUtils.asyncExec(executable.threadAccess, executable.runnable);
57                         return null;
58                 };
59                 return pool.schedule(c, delay, TimeUnit.MILLISECONDS);
60         }
61
62         private void shutdownThis() {
63                 ScheduledThreadPoolExecutor e = pool;
64                 if (e != null) {
65                         pool = null;
66                         ThreadUtils.shutdownAndAwaitTermination(e, 1000);
67                 }
68         }
69
70         public static synchronized void shutdown() {
71                 ExecutorWorker i = instance;
72                 if (i != null) {
73                         instance = null;
74                         i.shutdownThis();
75                 }
76         }
77
78 }