Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Java 9 Concurrency Cookbook, Second Edition

You're reading from   Java 9 Concurrency Cookbook, Second Edition Build highly scalable, robust, and concurrent applications

Arrow left icon
Product type Paperback
Published in Apr 2017
Publisher Packt
ISBN-13 9781787124417
Length 594 pages
Edition 2nd Edition
Languages
Concepts
Arrow right icon
Author (1):
Arrow left icon
Javier Fernández González Javier Fernández González
Author Profile Icon Javier Fernández González
Javier Fernández González
Arrow right icon
View More author details
Toc

Table of Contents (12) Chapters Close

Preface 1. Thread Management 2. Basic Thread Synchronization FREE CHAPTER 3. Thread Synchronization Utilities 4. Thread Executors 5. Fork/Join Framework 6. Parallel and Reactive Streams 7. Concurrent Collections 8. Customizing Concurrency Classes 9. Testing Concurrent Applications 10. Additional Information 11. Concurrent Programming Design

Monitoring an Executor framework

The Executor framework provides a mechanism that separates the implementation of tasks from thread creation and management to execute the tasks. If you use an executor, you only have to implement Runnable objects and send them to the executor. It is the responsibility of an executor to manage threads. When you send a task to an executor, it tries to use a pooled thread for executing the task in order to avoid the creation of new threads. This mechanism is offered by the Executor interface and its implementing classes as the ThreadPoolExecutor class.

In this recipe, you will learn what information you can obtain about the status of a ThreadPoolExecutor executor and how to obtain it.

Getting ready

The example of this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.

How to do it...

Follow these steps to implement the example:

  1. Create a class named Task that implements the Runnable interface:
        public class Task implements Runnable {
  1. Declare a private long attribute named milliseconds:
        private final long milliseconds;
  1. Implement the constructor of the class to initialize its attribute:
        public Task (long milliseconds) { 
this.milliseconds=milliseconds;
}
  1. Implement the run() method. Put the thread to sleep for the number of milliseconds specified by the milliseconds attribute:
        @Override 
public void run() {

System.out.printf("%s: Begin\n",
Thread.currentThread().getName());
try {
TimeUnit.MILLISECONDS.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s: End\n",
Thread.currentThread().getName());

}
  1. Implement the main class of the example by creating a class named Main with a main() method:
        public class Main { 

public static void main(String[] args) throws Exception {
  1. Create a new Executor object using the newCachedThreadPool() method of the Executors class:
        ThreadPoolExecutor executor = (ThreadPoolExecutor)
Executors.newCachedThreadPool();
  1. Create and submit 10 Task objects to the executor. Initialize the objects with a random number:
        Random random=new Random(); 
for (int i=0; i<10; i++) {
Task task=new Task(random.nextInt(10000));
executor.submit(task);
}
  1. Create a loop with five steps. In each step, write information about the executor by calling the showLog() method and putting the thread to sleep for a second:
        for (int i=0; i<5; i++){ 
showLog(executor);
TimeUnit.SECONDS.sleep(1);
}
  1. Shut down the executor using the shutdown() method:
        executor.shutdown();
  1. Create another loop with five steps. In each step, write information about the executor by calling the showLog() method and putting the thread to sleep for a second:
        for (int i=0; i<5; i++){ 
showLog(executor);
TimeUnit.SECONDS.sleep(1);
}
  1. Wait for the finalization of the executor using the awaitTermination() method:
        executor.awaitTermination(1, TimeUnit.DAYS);
  1. Display a message indicating the end of the program:
          System.out.printf("Main: End of the program.\n"); 
}
  1. Implement the showLog() method that receives Executor as a parameter. Write information about the size of the pool, the number of tasks, and the status of the executor:
        private static void showLog(ThreadPoolExecutor executor) { 
System.out.printf("*********************");
System.out.printf("Main: Executor Log");
System.out.printf("Main: Executor: Core Pool Size: %d\n",
executor.getCorePoolSize());
System.out.printf("Main: Executor: Pool Size: %d\n",
executor.getPoolSize());
System.out.printf("Main: Executor: Active Count: %d\n",
executor.getActiveCount());
System.out.printf("Main: Executor: Task Count: %d\n",
executor.getTaskCount()); System.out.printf("Main: Executor: Completed Task Count: %d\n",
executor.getCompletedTaskCount());
System.out.printf("Main: Executor: Shutdown: %s\n",
executor.isShutdown());
System.out.printf("Main: Executor: Terminating: %s\n",
executor.isTerminating());
System.out.printf("Main: Executor: Terminated: %s\n",
executor.isTerminated());
System.out.printf("*********************\n");
}

How it works...

In this recipe, you implemented a task that blocks its execution thread for a random number of milliseconds. Then, you sent 10 tasks to an executor, and while you were waiting for their finalization, you wrote information about the status of the executor to the console. You used the following methods to get the status of the Executor object:

  • getCorePoolSize(): This method returns an int number, which refers to the core number of threads. It's the minimum number of threads that will be in the internal thread pool when the executor is not executing any task.
  • getPoolSize(): This method returns an int value, which refers to the actual size of the internal thread pool.
  • getActiveCount(): This method returns an int number, which refers to the number of threads that are currently executing tasks.
  • getTaskCount(): This method returns a long number, which refers to the number of tasks that have been scheduled for execution.
  • getCompletedTaskCount(): This method returns a long number, which refers to the number of tasks that have been executed by this executor and have finished their execution.
  • isShutdown(): This method returns a Boolean value when the shutdown() method of an executor is called to finish its execution.
  • isTerminating(): This method returns a Boolean value when the executor performs the shutdown() operation but hasn't finished it yet.
  • isTerminated(): This method returns a Boolean value when the executor finishes its execution.

See also

  • The Creating a thread executor and controlling its rejected tasks recipe in Chapter 4, Thread Executors
  • The Customizing the ThreadPoolExecutor class and Implementing a priority-based Executor class recipes in Chapter 8, Customizing Concurrency Classes
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime