ThreadPool
Author: Maria Ivanova

This package contains the ThreadPoolManager interface, which is the face of the ThreadPoolManager Service. The task of the ThreadPoolManager is to provide created and started threads to its clients. The idea is to be saved time for the creation and starting of threads, when multiple, short-lived threads are used.

At startup the ThreadPoolManager creates and starts a given number of threads put in waiting state. While working new threads can be created but the number of all threads created by the ThreadPoolManager can not exceed a fixed limit.

When a client passes a job for execution to the ThreadPoolManager, it immediately tries to run the job. If there is an idle thread in the pool - the job is run, otherwise the job is put in waiting state until a thread finishes its current job and is ready to accept another one.

If the Runnable objects, passed to the ThreadPoolManager do not face the requirements of short-living, there is a possibility to slow down the work of thread processing as many jobs can be put in waiting state. Another problem appears when processing bad-written Runnable objects (never exiting their run method), then the number of free threads decreases, the number of already running threads will reach the limit, and it may occur that no more threads can be processed.

Here is a simple example of a job (RunnableSample) that is passed to the ThreadPoolManager for execution. The job is simple and common: it waits for an event to occur to process an operation; if the event does not occur for a given time period (1 second in our example) another operation is processed. In the example below the event is the "check" flag to be turned on, and the operations are "System.out.println".

public class RunnableSample implements Runnable { private Object synch; private String name; private boolean check; //Constructs a RunnableSample. public RunnableSample(String name) { this.name = name; check = false; synch = new Object(); } //This method is executed by the ThreadPoolManager. public void run() { synchronized (synch) { System.out.println("Job " + name + " starts running!"); if (!check) { try { synch.wait(1000); } catch (InterruptedException e) { } } if (check) { System.out.println("OK: CHECKED"); } else { System.out.println("NOT OK: NOT CHECKED"); } } } //Turns the check flag on. public void checkIt() { synchronized (synch) { check = true; synch.notify(); } } //Wakes up this Runnable object, causing exiting its run method. public void stopIt() { synchronized (synch) { synch.notify(); } } }

The sample code , which follows, gets reference to the ThreadPoolManager, and passes a RunnableSample job for execution.

import org.eclipse.equinox.util.threadpool.ThreadPoolManager; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; ... BundleContext bc; ServiceReference thManRef; ThreadPoolManager thMan; ... thManRef = bc.getServiceReference("org.eclipse.equinox.util.threadpool.ThreadPoolManager"); thMan = (ThreadPoolManager) bc.getService(thManRef); String jobName = "RunnableSample"; //ThreadPoolManager will execute the job, as soon as a free thread is available thMan.execute(new RunnableSample(jobName), jobName); ...

The ThreadPoolManager has two system properties, which define the limits of the thread pool:

- equinox.util.threadpool.minThreads : default value: 4; this property defines the minimum number of idle threads. The property cannot be 1 - if it is set to 1, automatically it is turned to 2.

- equinox.util.threadpool.maxThreads : default value: 48; this property specifies the upper limit for the number of threads in the thread pool. The real limit is calculated using the formula: (((int)(max/min)) * min).

- equinox.util.threadpool.autoMaximum : default value: false; if this property is set to true the then if there are more then 10 waitng jobs the maximum can be exceeded.

- equinox.util.threadpool.ignoreMaximum : default value: false; if this property is set to true, the Thread Pool Manager will not regard the maxThread property and will always create new threads when there are no available.

- equinox.util.threadpool.useNames : default value: false; if this property is set to true, allows assigning names to threads, executing runnable jobs.

- equinox.util.threadpool.percent : default value: 30; this property specifies what default percent of the maximum number of threads a bundle can occupy from the thread pool.