aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/concurrent/BlockingThreadPool.java
blob: a6d7e9bcbe5177d49fdb435561aee47d700bc4b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package cgeo.geocaching.concurrent;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * BlockingThreadPool restricts the amount of parallel threads executing Runnables.
 */
public class BlockingThreadPool {
    /** The queue holding the Runnable. **/
    private BlockingQueue<Runnable> queue = null;
    /** The Executor. **/
    private ThreadPoolExecutor executor;

    /**
     * Creates a ThreadPool with a given maximum of parallel threads running.
     * Idle threads will be stopped until new threads are added.
     *
     * @param poolSize
     *            Maximum amout of parallel Threads
     * @param priority
     *            The Thread priority e.g. Thread.MIN_PRIORITY
     */
    public BlockingThreadPool(int poolSize, int priority) {
        ThreadFactory threadFactory = new PriorityThreadFactory(priority);
        this.queue = new ArrayBlockingQueue<>(poolSize, true);
        this.executor = new ThreadPoolExecutor(0, poolSize, 5, TimeUnit.SECONDS, this.queue);
        this.executor.setThreadFactory(threadFactory);
    }

    /**
     * Add a runnable to the pool. This will start the core threads in the underlying
     * executor and try to add the Runnable to the pool. This method waits until timeout
     * if no free thread is available.
     *
     * @param task
     *            The Runnable to add to the pool
     * @param timeout
     *            The timeout to wait for a free thread
     * @param unit
     *            The timeout unit
     * @return true/false successful added
     * @throws InterruptedException
     *             Operation was interrupted
     */
    public boolean add(Runnable task, int timeout, TimeUnit unit) throws InterruptedException {
        this.executor.setCorePoolSize(this.executor.getMaximumPoolSize());
        this.executor.prestartAllCoreThreads();
        boolean successfull = this.queue.offer(task, timeout, unit);
        this.executor.setCorePoolSize(0);
        return successfull;
    }
}