Table of Contents
Benefits of thread pool
Five ways to create a thread pool
Cached Thread Pool CachedThreadPool
Fixed capacity thread pool FixedThreadPool
Single thread pool SingleThreadExecutor
Scheduled ThreadPool
ThreadPoolExecutor creates a thread pool (highly recommended)
Detailed explanation of the seven parameters of ThreadPoolExecutor
workQueue
handler
如何触发拒绝策略和线程池扩容?
Home Java javaTutorial How to create a Java thread pool

How to create a Java thread pool

May 16, 2023 am 08:43 AM
java

Benefits of thread pool

  • It can realize the reuse of threads and avoid re-creating and destroying threads. Creating threads and destroying threads is very expensive for the CPU.

  • You can limit the maximum number of threads that can be created, and dynamically adjust thread pool parameters according to your own machine performance to improve application performance.

  • Provides functions such as scheduled execution and concurrency control.

  • Unified management of threads.

Five ways to create a thread pool

1: Cache thread pool (not recommended)

2: Fixed capacity thread pool (not recommended)

3: Single thread pool (not recommended)

4: Scheduled task thread pool (not recommended)

5: Create a thread pool through the ThreadPoolExecutor construction method (developed by Alibaba The manual is highly recommended)

The first four ways to create a thread pool are all created through the static methods of Executors.

Cached Thread Pool CachedThreadPool

	ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            executorService.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
                }
            });
        }
Copy after login

Why is the cache thread pool not recommended?

Source code analysis

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
    }
Copy after login
 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
    }
Copy after login

Through the above two code snippets, we can see that the maximumPoolSize of CachedThreadPool is the maximum value of Integer 2147483647, which is equivalent to unlimited thread creation, and creating threads requires memory Yes, this will cause memory overflow, and ordinary machines do not use such a large memory to create such a large number of threads.

Fixed capacity thread pool FixedThreadPool

newFixedThreadPool(int num), num is the number of fixed threads we want to specify

	ExecutorService executorService = Executors.newFixedThreadPool(5);

      for (int i = 0; i < 10; i++) {
          final int finalI = i;
          executorService.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });
      }
Copy after login

Output:

pool-1-thread-5run>4
pool-1-thread-4run>3
pool-1-thread-5run> 5
pool-1-thread-3run>2
pool-1-thread-3run>8
pool-1-thread-3run>9
pool-1-thread-2run>1
pool-1-thread-1run>0
pool-1-thread- 5run>7
pool-1-thread-4run>6

It can be seen that thread reuse is achieved.

Why is FixedThreadPool a fixed thread pool?

Source code analysis

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    }
Copy after login

It can be seen from this source code that the number of core threads (corePoolSize) and the maximum number of threads (maximumPoolSize) are both nThreads, because only in this way, the thread pool will not be expanded. , the number of threads is fixed.

Single thread pool SingleThreadExecutor

	ExecutorService executorService = Executors.newSingleThreadExecutor();

      for (int i = 0; i < 10; i++) {
          final int finalI = i;
          executorService.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });

      }
Copy after login

Why does SingleThreadExecutor only contain one thread?

Source code analysis

public static ExecutorService newSingleThreadExecutor() {
        return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
    }
Copy after login

It can be seen from this source code that the number of core threads (corePoolSize) and the maximum number of threads (maximumPoolSize) are both 1, so it only contains one thread.

Scheduled ThreadPool

	  int initDelay=10; //初始化延时
      int period=1;//初始化延迟过了之后,每秒的延时

      ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);

      scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
          @Override
          public void run() {
              System.out.println(Thread.currentThread().getName()+"<thread->run>");
          }
      },initDelay,period, TimeUnit.SECONDS);
Copy after login

The effect of this code is: wait 10 seconds after the program runs, then output the first result, and then output the result every 1 second.

Why is ScheduledThreadPool not recommended?

Source code analysis

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, 2147483647, 10L, TimeUnit.MILLISECONDS, new ScheduledThreadPoolExecutor.DelayedWorkQueue());
    }
Copy after login

It can be seen that the maximum number of threads (maximumPoolSize) of ScheduledThreadPool is the maximum value of Integer 2147483647, which is equivalent to unlimited creation of threads, and creating threads requires memory, so It will cause memory overflow, and ordinary machines do not use such a large memory to create such a large number of threads.

	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20,
              2L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5),
              Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

      for (int i = 0; i < 12; i++) {
          final int finalI = i;
          threadPoolExecutor.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });
      }
Copy after login
Detailed explanation of the seven parameters of ThreadPoolExecutor
	public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        
    }
Copy after login
  • corePoolSize: the number of core threads. Once these threads are created, they will not be destroyed and will always exist. The thread pool has no threads by default. When a task arrives, a thread will be created through ThreadFactory and will always exist.

  • maximumPoolSize: Maximum number of threads. The number of non-core threads = maximumPoolSize-corePoolSize. The number of non-core threads is actually the number of scalable threads and may be destroyed.

  • keepAliveTime: The idle survival time of non-core threads. When the number of non-core threads generated through expansion is still idle after keepAliveTime, these non-core threads will be destroyed.

  • unit: the time unit of keepAliveTime, for example: seconds

  • workQueue: waiting area. When a task of >corePoolSize comes, the task will be stored in the blocking queue of workQueue, waiting for other threads to process it.

  • threadFactory: Thread factory. A way to create threads.

  • handler: Rejection strategy. When the capacity of >maximum number of threads workQueue is reached, the rejection policy will be executed

workQueue

ArrayBlockingQueue: bounded blocking queue. The queue has a size limit. When the capacity is exceeded, the expansion or rejection policy will be triggered.

	public ArrayBlockingQueue(int capacity) {
        this(capacity, false);
    }
Copy after login

LinkedBlockingQueue: Unbounded blocking queue, the queue has no size limit, and may cause memory overflow.

	 public LinkedBlockingQueue() {
        this(2147483647);
    }
Copy after login
handler

AbortPolicy: Throw an exception directly

	public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());
        }
    }
Copy after login

DiscardPolicy: No operation is performed. Silently discard the task

	public static class DiscardPolicy implements RejectedExecutionHandler {
        public DiscardPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }
Copy after login

DiscardOldestPolicy: Discard the longest existing task

	public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        public DiscardOldestPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }

        }
    }
Copy after login

CallerRunsPolicy: Let the thread that submitted the task process the task

	public static class CallerRunsPolicy implements RejectedExecutionHandler {
        public CallerRunsPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }

        }
    }
Copy after login

threadFactory

	ThreadFactory threadFactory = Executors.defaultThreadFactory();

      threadFactory.newThread(new Runnable() {
          @Override
          public void run() {
              System.out.println("threadFactory");
          }
      }).start();
Copy after login
如何触发拒绝策略和线程池扩容?
	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20,
              2L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5),
              Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

      for (int i = 0; i < 26; i++) { //并发数26
          final int finalI = i;
          threadPoolExecutor.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });
      }
      /**
       * 核心线程数=10,最大线程数=20,故可扩容线程数=20-10
       * BlockingQueue的大小为5,故等待区的大小为5,也就是当并发数<=核心线程数+5不会扩容,并发数大于16才会扩容
       *
       * 触发扩容:并发数>核心线程数+阻塞队列的大小
       * 对于这段代码,如果来了26个并发,10个并发会被核心线程处理,5个会在等待区,剩下11个会因为等待区满了而触发扩容
       * 因为这里最多能够扩容10个,这里却是11个,所以会触发拒绝策略
       */
Copy after login
  • 为什么这段代码会触发拒绝策略

对于这段代码,如果来了26个并发,10个并发会被核心线程处理,5个会在等待区,剩下11个会因为等待区满了而触发扩容,但是又因为因为这里最多能够扩容10个,这里却是11个,所以会触发拒绝策略。

  • 怎么触发扩容

触发扩容:并发数>核心线程数(corePoolSize)+阻塞队列(workQueue)的大小

  • 使用Java纯手写一个线程池

The above is the detailed content of How to create a Java thread pool. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Perfect Number in Java Perfect Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Smith Number in Java Smith Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

Create the Future: Java Programming for Absolute Beginners Create the Future: Java Programming for Absolute Beginners Oct 13, 2024 pm 01:32 PM

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

See all articles