Part 11: java.util.concurrent - CachedThreadPool Example

Part 11: java.util.concurrent - CachedThreadPool Example
This article will discuss about Thread pool that can reuse previously constructed threads when they are available. From Java 5.0+ one can get such pool from Executors using following method –
public static ExecutorService newCachedThreadPool()
Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. 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. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors.


Example-
Suppose we have 100 properties files in an application. We have one thread that can read properties file and return a map value. We want to optimize the time to read all 100 properties file by using concurrent reading. Here optimize means – we need a perfect balance between CPU Utilization and total time consumed by reading process.

Pseudo code –  READER THREAD

Config Reader implements Callable<Map<String, String>
try{
       // Get the file name in the constructor of thread
    // Check if File exists
    // Read the file and retrun the map object
}catch(Exception e){
         //release all the resource
        //return null
}

Main THREAD-
         // Get a Cached thread pool from Executors
 try{
     // Get the list of all properties file in the directory
    // Create a READER THREAD by passing the name of file
    // store the READER thread in the a list
    //release all the thread in one go and get the Map objects
}catch(Exception e){
                 //release all the resources
                // print the stack trace
}finally{
         //shutdown the thread pool
}

package  com.jovialjava.blog.threads;

import  java.io.File;
import  java.io.FileInputStream;
import  java.util.ArrayList;
import  java.util.List;
import  java.util.Properties;
import  java.util.concurrent.Callable;
import  java.util.concurrent.ExecutorService;
import  java.util.concurrent.Executors;
import  java.util.concurrent.Future;

class  CachedReader  implements  Callable < Properties >  {

    
private  String name  =   null ;

    
public  CachedReader(String name) {
        
this .name  =  name;
    }

    
public  Properties call() {
        
try  {
            File f 
=   new  File(name);
            Properties prop 
=   new  Properties();
            
if  (f.exists()  &&  f.canRead()  &&  f.isFile()) {
                FileInputStream in 
=   new  FileInputStream(f);
                prop.load(in);
                
return  prop;
            } 
else  {
                System.err.println(
" Please check about this file:[ "   +  f.getAbsolutePath()  +   " ] " );
                
return   null ;
            }
        } 
catch  (Exception e) {
            e.printStackTrace();
            
return   null ;
        }
    }
}

public   class  CachedThreadPoolExample {
    
public   static  String directory  =   " config " ;
    
private   static  ExecutorService executorPool  =   null ;
    
private   static   int  MAX_THREADS  =   20 ;

    
public   static   void  main(String args) {
        
try  {
            File dir 
=   new  File(directory);
            
if  (dir.isDirectory()) {
                List
< Callable < Properties >>  fileList  =   new  ArrayList < Callable < Properties >> ();
                String[] files 
=  dir.list();
                
/**
                 * Optimization - Reuse the the threads.
                 
*/
                executorPool 
=  Executors.newCachedThreadPool();

                
for  (String file : files) {
                    Callable
< Properties >  reader  =   new  CachedReader(dir.getAbsolutePath()  +  File.separator  +  file);
                    fileList.add(reader);
                }
                List
< Future < Properties >>  results  =  executorPool.invokeAll(fileList);
                
/**
                 * Check how many success and how many failure
                 
*/
                
int  success  =   0 , failure  =   0 ;
                
for  (Future < Properties >  result : results) {
                    
if  (result.get()  ==   null ) {
                        failure
++ ;
                    } 
else  {
                        success
++ ;
                    }
                }
                System.out.println(
" Total number of files [ "   +  fileList.size()  +   " ] " );
                System.out.println(
" Success Count [ "   +  success  +   " ] " );
                System.out.println(
" Failure Count [ "   +  failure  +   " ] " );
            } 
else  {
                
throw   new  IllegalArgumentException( " There is no such directory name - "   +  directory);
            }
        } 
catch  (Exception e) {
            e.printStackTrace();
        } 
finally  {
            
if  (executorPool  !=   null ) {
                executorPool.shutdown();
            }
        }
    }
}


你可能感兴趣的:(Part 11: java.util.concurrent - CachedThreadPool Example)