ExecutorService

のの·2021년 1월 4일

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 sizeConsiderations
CPU IntensiveCpu core countHow many other applications(or other executors/threads) are running on the same CPU
IO 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

  1. FixedThreadPool = newFixedThreadPool

  2. 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());
        }
    }
}

  1. 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());
        }
    }
}

  1. 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

ParameterFixedThreadPoolCachedThreadPoolScheduledThreadPoolSingleThreaded
corePoolsizeconstructor-arg0constructor-arg1
maxPoolSizesame as corePoolSizeInteger.MAX_VALUEInteger.MAX_VALUE1
keepAliveTime0 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();
        }
    }
}
profile
wannabe developer

0개의 댓글