X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.utils.thread%2Fsrc%2Forg%2Fsimantics%2Futils%2Fthreads%2FExecutorWorker.java;h=698d99e97a036fa8305761132ebb60162b4fefbb;hp=e63b304e9e27c7df7ca58f2efbea9ac7daa3a2ee;hb=951846b17c8c02759b7a319b0f2952cafacb8bea;hpb=d90a13d82876ecd36bd3a73c00c879d6619376d1 diff --git a/bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/ExecutorWorker.java b/bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/ExecutorWorker.java index e63b304e9..698d99e97 100644 --- a/bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/ExecutorWorker.java +++ b/bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/ExecutorWorker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * Copyright (c) 2007, 2018 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -8,58 +8,71 @@ * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - added shutdown facilities *******************************************************************************/ -/* - * - * @author Toni Kalajainen - */ + package org.simantics.utils.threads; import java.util.concurrent.Callable; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; - +/** + * @author Toni Kalajainen + * @author Tuukka Lehtonen + */ public class ExecutorWorker { - - private static ExecutorWorker instance; - - static class DelayedExecution implements Comparable { - Executable executable; - long executionTime; - @Override - public int compareTo(DelayedExecution o) { - if (o.executionTimeexecutionTime) return 1; - return 0; - } - } - public static ExecutorWorker getInstance() - { - if (instance == null) - instance = new ExecutorWorker(); + private static volatile ExecutorWorker instance; + + public static ExecutorWorker getInstance() { + if (instance == null) { + synchronized (ExecutorWorker.class) { + if (instance == null) + instance = new ExecutorWorker(); + } + } return instance; } - - ExecutorWorker() { - } - ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1); - + private ExecutorWorker() {} + + private final AtomicInteger counter = new AtomicInteger(0); + private final ThreadGroup threadGroup = new ThreadGroup("ExecutorWorker-Group"); + private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1, r -> { + Thread t = new Thread(threadGroup, r, "ExecutorWorker-" + (counter.incrementAndGet())); + if (!t.isDaemon()) + t.setDaemon(true); + if (t.getPriority() != Thread.NORM_PRIORITY) + t.setPriority(Thread.NORM_PRIORITY); + return t; + }); + public synchronized ScheduledFuture timerExec(final Executable executable, int delay) { - Callable c = new Callable() { - @Override - public Object call() throws Exception { - // FIXME: executable.runnable gets called twice! - ThreadUtils.asyncExec(executable.threadAccess, executable.runnable); - //executable.runnable.run(); - return null; - } - }; + Callable c = () -> { + ThreadUtils.asyncExec(executable.threadAccess, executable.runnable); + return null; + }; return pool.schedule(c, delay, TimeUnit.MILLISECONDS); } + private void shutdownThis() { + ScheduledThreadPoolExecutor e = pool; + if (e != null) { + pool = null; + ThreadUtils.shutdownAndAwaitTermination(e, 1000); + } + } + + public static synchronized void shutdown() { + ExecutorWorker i = instance; + if (i != null) { + instance = null; + i.shutdownThis(); + } + } + }