In order to prevent overhead of thread creation and reuse existed threads Java supports thread pools since version 1.5. The mechanism of thread pool is based on the equally called pattern. Roughly speaking, thread pool is a queue of initialized threads which makes its usage less expensive neither than using classic single Thread approach.
Java Virtual Machine provides fast access to the queue and every thread has its own instruction to be performed; instructions are customized with objects that implement Callable or Runnable.
Java Virtual Machine provides fast access to the queue and every thread has its own instruction to be performed; instructions are customized with objects that implement Callable or Runnable.
Instead of creating threads directly with
operations like Thread th = new Thread(); you may use instance of Executor interface.
Executor executor = new Executor() { public void execute(Runnable command) { command.run(); } }; executor.execute(someRunnableInstance);
Executor uses already existed thread and
makes the thread to perform operations defined at someRunnableInstance.
ExecutorService (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html)
extends Executor interface within new very useful methods. If you’d like to
have custom class which implements ExecutorService you must override about 13
methods (jdk 1.8.0.31)
Let’s take a look on a few of them
- Future<?> submit(Runnable task), <T> Future<T> submit(Callable<T> task) – submits task to be executed.
- void shutdown() – initiates the shutdown of the submitted task (no guarantee that the task will be stopped)
The main advantage of ExecutorService is in
object which can be returned by “submit” method, this object implements Future
interface and represents a result of asynchronous operation (Read more). Method
‘submit’ extends base method execute, the only difference is in returned value.
There are many classes implement
ExecutorService interface: ThreadPoolExecutor, ForkJoinPool, FixedthreadPool
and more. Choose any depending you task.
Some instances of ExecutorService may be created
with Executors factory. Take a look on example.
public static void main(String... args) throws InterruptedException { System.out.println("started"); ScheduledExecutorService service = Executors.newScheduledThreadPool(2); service.schedule(new Runnable() { public void run() { System.out.println("Hey from the pool " + Thread.currentThread().getName()); } }, 10000, TimeUnit.MILLISECONDS); System.out.println("finished"); }
The output of this code will be
started
finished
Hey
from the pool pool-1-thread-1
…and we got stuck application
Even when we had left main method block the
program didn’t stop its execution because of the scheduled thread. We set
timeout 10 seconds since the moment after submit so the thread’s message ‘Hey from the pool pool-1-thread-1’ is printed with a delay. We also didn’t close the executor service
correctly, in order to do that service.shutdown() must be invoked. Getting this
done we will have the same output but application stops working right after showing
the message from the scheduled thread.
NOTE: always check your code for service.shutdown()
Some more samples around Executors factory
a) ExecutorService service =
Executors.newCachedThreadPool();
//
creates a thread pool that creates new threads as needed, but will reuse
previously constructed threads when they are available. Threads that have not
been used for sixty seconds are terminated and removed from the cache. Thus, a
pool that remains idle for long enough will not consume any resources
b) ExecutorService service =
Executors.newSingleThreadExecutor();
//
creates an Executor that uses a single worker thread operating off an unbounded
queue
c) ExecutorService service =
Executors.newScheduledThreadPool(10);
//
creates a thread pool that can schedule commands to run after a given delay, or
to execute periodically
No comments:
Post a Comment