Thread Pool for Multithreaded Learning Notes 7

Executors

Create a class of thread pools that provide four types of thread pools:

  • newCachedThreadPool creates a cacheable thread pool that provides flexibility to recycle idle threads if the length of the thread pool exceeds processing requirements and creates new threads if none is available
    Sample code:
public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<String> c = () -> "Hello Callable";

        ExecutorService service = Executors.newCachedThreadPool();
        //asynchronous
        Future<String> future = service.submit(c);
        //block
        System.out.println(future.get());

        service.shutdown();
    }
}
  • newFixedThreadPool creates a fixed-length thread pool that controls the maximum number of concurrent threads. Threads that exceed it will wait in the queue
  • newScheduledThreadPool creates a fixed-length thread pool that supports timed and periodic task execution
  • newSingleThreadExecutor creates a single-threaded thread pool that only executes tasks with a single worker thread, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority)

Callable

Callable is a task, similar to Runnable, but a Callable task has a return value. Usually, the Callable task is executed with a thread pool and returns a Future containing the result of Callable execution. This operation is asynchronous, then the result is obtained through the Future.get() blocking method

Future

Store results from executing tasks

FutureTask

Instead of Callable Task+Future,FutureTask implements the RunnableFuture interface, which inherits both Runnable and Future interfaces (interfaces can inherit more than two interfaces at the same time), so FutureTask itself is a task and Future, simply using the following

public class FutureTaskDemo {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        FutureTask<Integer> task = new FutureTask<>(() -> {
            TimeUnit.MILLISECONDS.sleep(500);
            return 1000;
        }); //new Callable () { Integer call();}

        new Thread(task).start();//Thread pools are also available here
        //block
        System.out.println(task.get());
    }
}

CompletableFuture

Used to manage the results of multiple Future s, simply use the following

public class CompletableFutureDemo {
    public static void main(String[] args) {
        long start, end;

        start = System.currentTimeMillis();

        CompletableFuture<Double> futureTM = CompletableFuture.supplyAsync(CompletableFutureDemo::priceOfTM);
        CompletableFuture<Double> futureTB = CompletableFuture.supplyAsync(CompletableFutureDemo::priceOfTB);
        CompletableFuture<Double> futureJD = CompletableFuture.supplyAsync(CompletableFutureDemo::priceOfJD);

        CompletableFuture.allOf(futureTM, futureTB, futureJD).join();

        end = System.currentTimeMillis();
        System.out.println("use completable future! " + (end - start));

    }

    private static double priceOfTM() {
        delay();
        return 1.00;
    }

    private static double priceOfTB() {
        delay();
        return 2.00;
    }

    private static double priceOfJD() {
        delay();
        return 3.00;
    }

    private static void delay() {
        int time = new Random().nextInt(500);
        try {
            TimeUnit.MILLISECONDS.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("After %s sleep!\n", time);
    }
}

ThreadPoolExecutor and seven parameters

Create a thread pool construction method with seven parameters, as shown below

  • corePoolSize Thread Pool Core Thread Size is idle and will not be recycled
  • Maximum PoolSize Thread Pool Maximum number of threads that will be recycled when idle time is reached
  • Ke keepAliveTime idle thread lifetime
  • unit Space Thread Lifetime unit
  • workQueue Work Queue
    When a new task is submitted, it is first entered into the work queue and then removed from the queue when the task is scheduled.There are four work queues available in jdk:

①ArrayBlockingQueue

Bounded blocking queue based on array, sorted by FIFO.When a new task comes in, it is placed at the end of the queue, and a bounded array prevents resource depletion.When the number of threads in the thread pool reaches corePoolSize and a new task comes in, the task is placed at the end of the queue waiting to be scheduled.If the queue is full, a new thread is created, and if the number of threads has reached maxPoolSize, a rejection policy is executed.

②LinkedBlockingQuene

An unbounded blocking queue based on a chained list (with the maximum capacity of Interger.MAX) sorted by FIFO.Because the queue is nearly unbounded, when the number of threads in the thread pool reaches corePoolSize and new tasks come in, the queue is always saved without creating new threads until maxPoolSize, so the parameter maxPoolSize does not really work when using this work queue.

③SynchronousQuene

A blocked queue that does not cache tasks, and the producer puts a task in it until the consumer takes it out.That is, when a new task comes in, it is not cached, but directly scheduled to execute the task, if no threads are available, a new thread is created, and if the number of threads reaches maxPoolSize, a rejection policy is executed.

④PriorityBlockingQueue

Unbounded blocking queue with priority implemented by parameter Comparator

  • threadFactory Thread Factory

The factory used when creating a new thread, which can be used to set the thread name, whether it is a daemon thread, and so on

  • handler rejection policy
    When the task in the work queue has reached the maximum limit and the number of threads in the thread pool has reached the maximum limit, what happens if a new task is committed.The rejection policy here is to solve this problem. There are four rejection policies in jdk:

①CallerRunsPolicy

Under this policy, the run method of the rejected task is executed directly in the caller thread, and the task is discarded unless the thread pool has shutdown.

②AbortPolicy

Under this policy, the task is discarded directly and a RejectedExecutionException exception is thrown.

③DiscardPolicy

Under this strategy, you simply discard the task and do nothing.

④DiscardOldestPolicy

Under this policy, discard the earliest task in the queue and try to queue the rejected task

The code for simple use is as follows:

public class ThreadPoolExecutorDemo {
    static class Task implements Runnable {
        private int i;

        public Task(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Task " + i);
            try {
                System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            return "Task{" +
                    "i=" + i +
                    '}';
        }
    }

    public static void main(String[] args) {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4,
                60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(4),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());

        for (int i = 0; i < 8; i++) {
            tpe.execute(new Task(i));
        }

        System.out.println(tpe.getQueue());

        tpe.execute(new Task(100));

        System.out.println(tpe.getQueue());

        tpe.shutdown();
    }
Twenty-one original articles have been published. Complimented 1. Visits 426
Private letter follow

Keywords: JDK

Added by unerd.co.uk on Sat, 25 Jan 2020 11:17:06 +0200