ExecutorService



public class TheadMain {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new Task());
            thread.start();
        }
        System.out.println("Thread Name: " + Thread.currentThread().getName());
    }
    static class Task implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread Name: " + Thread.currentThread().getName());
        }
    }
}
Thread Name: Thread-7
Thread Name: main
Thread Name: Thread-4
Thread Name: Thread-2
Thread Name: Thread-9
Thread Name: Thread-5
Thread Name: Thread-0
Thread Name: Thread-6
Thread Name: Thread-8
Thread Name: Thread-1
Thread Name: Thread-3
ThreadPool
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TheadMain {
    public static void main(String[] args) {

        ExecutorService service = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            service.execute(new Task());
        }
        System.out.println("Thread Name: " + Thread.currentThread().getName());
    }
    static class Task implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread Name: " + Thread.currentThread().getName());
        }
    }
}
Thread Name: pool-1-thread-9
Thread Name: pool-1-thread-3
Thread Name: pool-1-thread-5
Thread Name: pool-1-thread-4
Thread Name: pool-1-thread-8
Thread Name: pool-1-thread-10
Thread Name: pool-1-thread-2
Thread Name: pool-1-thread-7
Thread Name: main
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-6
ieal number of tp is the same as the number of cpu core
int coreCount = Runtime.getRuntime().availableProcessors()
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TheadMain {
    public static void main(String[] args) {

        // get count of available cores
        int coreCount = Runtime.getRuntime().availableProcessors();
        System.out.println(coreCount);
        ExecutorService service = Executors.newFixedThreadPool(coreCount);
        for (int i = 0; i < 10; i++) {
            service.execute(new Task());
        }
        System.out.println("Thread Name: " + Thread.currentThread().getName());
    }
    static class Task implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread Name: " + Thread.currentThread().getName());
        }
    }
}

4
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-1
Thread Name: pool-1-thread-2
Thread Name: pool-1-thread-3
Thread Name: main
Thread Name: pool-1-thread-4

Task TypeIdeal pool sizeConsiderationsCPU IntensiveCpu core countHow many other applications(or other executors/threads) are running on the same CPUIO intensiveHighExact number will depend on rate of task submissions and average task wait time. Too many thread will increase memory consumption too
Type of Pools

  • FixedThreadPool = newFixedThreadPool

  • CachedThreadPool
    Synchronous queue(can hold only 1 task)
    If all threads are busy, then create a new thread for the task and place it in the pool
    Life cycle: If thread is idle for 60 seconds (no task to execute) then kill the thread
  • import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TheadMain {
        public static void main(String[] args) {
    
            ExecutorService service = Executors.newCachedThreadPool();
            for (int i = 0; i < 100; i++) {
                service.execute(new Task());
            }
            System.out.println("Thread Name: " + Thread.currentThread().getName());
        }
        static class Task implements Runnable{
            @Override
            public void run() {
                System.out.println("Thread Name: " + Thread.currentThread().getName());
            }
        }
    }
    
    

  • ScheduledThreadPool
    Service.schedule
    Service.scheduleAtFixedRate
    Service.scheduleAtFixedDelay
    Schedule the tasks to run based on time delay (and retrigger for fixedRate/fixedDelay)
    Life Cycle: More threads are created if required
  • import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class TheadMain {
        public static void main(String[] args) {
    
            // for scheduling of tasks
            ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
    
            // task to run after 10 seconds delay
            service.schedule(new Task(),10,TimeUnit.SECONDS);
            // taks to run repeatedly every 10 seconds
            service.scheduleAtFixedRate(new Task(), 15,10, TimeUnit.SECONDS);
            // task to run repeatedely 10 seconds after previous task completes
            service.scheduleWithFixedDelay(new Task(), 15,10,TimeUnit.SECONDS);
        }
        static class Task implements Runnable{
            @Override
            public void run() {
                System.out.println("Thread Name: " + Thread.currentThread().getName());
            }
        }
    }
    
    

  • SingleThreadedExecutor
    Life Cycle : Recreates thread if killed because of the task.
  • ExecutorService service = Executors.newFixedThreadPool(10);
    
    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }
    
    
    ジェネレータパラメータ
    corePoolSize
    Type: int
    Minumum/Base size of the pool
    maxPoolSize
    Type: int
    Maximum size of the pool
    KeepAliveTime + unit
    Type: long
    Time to keep an idle thread alive(after which it is killed)
    workQueue
    Type: BlockingQueue
    Queue to store the tasks from which threads fetch from
    threadFactory
    Type: ThreadFactory
    The factory to use to create new threads
    handler
    Type: RejectedExecutionHandler
    Callback to use when tasks submitted are rejected
    Pool size changes
    ParameterFixedThreadPoolCachedThreadPoolScheduledThreadPoolSingleThreadedcorePoolsizeconstructor-arg0constructor-arg1maxPoolSizesame as corePoolSizeInteger.MAX_VALUEInteger.MAX_VALUE1keepAliveTime0 seconds60 seconds60 seconds0 seconds
    Queue types
    Task rejections
    Life cycle methods
    Runnable interface
    Thread Task return
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.*;
    
    public class TheadMain {
        public static void main(String[] args) {
    
            ExecutorService service = Executors.newFixedThreadPool(10);
    
            List<Future> allFuture = new ArrayList<>();
            for(int i=0; i<100;i++) {
                Future<Integer> future = service.submit(new Task());
                allFuture.add(future);
            }
            // 100 futures, with 100 placeholders;
    
            // perform some unrelated operations
    
            // 100 sec
            for(int i=0; i<100; i++) {
                Future<Integer> future = allFuture.get(i);
                try {
                    Integer result = future.get(); // blocking
                    System.out.println("Result of future #" + i + "=" + result);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Thread Name: " + Thread.currentThread().getName());
        }
        static class Task implements Callable<Integer>{
            @Override
            public Integer call() throws Exception {
                Thread.sleep(3000);
                return new Random().nextInt();
            }
        }
    }