Location>code7788 >text

Thread Pool King of the Pit !

Popularity:28 ℃/2024-12-15 00:50:28

preamble

Thread pooling is a powerful tool for handling multithreading in Java, but it's more than just a "just use it and be done with it" tool.

Many partners have stepped on many potholes when using thread pools because of misconfiguration or ignoring details.

Today, I'd like to talk to you about the 10 pitfalls in thread pooling and how to avoid them, hopefully it will be helpful to you.

1. Use Executors directly to create the thread pool.

Many beginners create thread pools by directly using theExecutors Shortcuts provided:

ExecutorService executor = (10);

What's the problem?

  • unbounded queuenewFixedThreadPool The queue used isLinkedBlockingQueue, it is an unbounded queue and task stacking may lead to memory overflow.
  • Infinite thread growthnewCachedThreadPool It creates unlimited threads, which may exhaust system resources when the number of tasks spikes.

Example: Risk of Memory Overflow

ExecutorService executor = (2);
for (int i = 0; i < 1000000; i++) {
    (() -> {
        try {
            (1000);
        } catch (InterruptedException e) {
            ();
        }
    });
}

The number of tasks is much larger than the number of threads, leading to infinite stacking of tasks in the queue, which may eventually lead to aOutOfMemoryError

method settle an issue

utilizationThreadPoolExecutorand explicitly specify the parameters:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    2,
    4,
    60L,
    ,
    new ArrayBlockingQueue<>(100), // bounded queue
    new () // rejection strategy
);

2. Misconfigured number of threads

Many people configure thread pool parameters randomly, such as 10 core threads and 100 max threads, which seems fine, but this can lead to performance problems or wasted resources.

Example: Thread overload due to misconfiguration

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10, // Number of core threads
    100, // Maximum number of threads
    60L,
    ,
    new ArrayBlockingQueue<>(10)
);

for (int i = 0; i < 1000; i++) {
    (() -> {
        try {
            (5000); // Simulating time-consuming tasks
        } catch (InterruptedException e) {
            ();
        }
    });
}

This configuration creates a large number of threads and system resources are exhausted when tasks surge.

The right way to configure

Choose a reasonable number of threads based on the type of task:

  • CPU-intensive: The number of threads is recommended to be set toCPU cores + 1
  • IO Intensive: The number of threads is recommended to be set to2 * CPU cores

Example:

int cpuCores = ().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    cpuCores + 1,
    cpuCores + 1,
    60L,
    ,
    new ArrayBlockingQueue<>(50)
);

3. Ignoring the selection of task queues

Task queues directly affect the behavior of the thread pool. If you choose the wrong type of queue, it can cause a lot of hidden problems.

Common Queue Pitfalls

  • unbounded queue: Tasks stack up infinitely.
  • bounded queue: A full queue triggers the reject policy.
  • Priority Queue: It can easily lead to frequent preemption of low-priority tasks by high-priority tasks.

Example: Task stacking causes problems

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    2,
    4,
    60L,
    ,
    new LinkedBlockingQueue<>()
);

for (int i = 0; i < 100000; i++) {
    (() -> (().getName()));
}

Improved methodology: Use bounded queues to avoid infinite stacking of tasks.

new ArrayBlockingQueue<>(100);

4. Forgetting to close the thread pool

Some of you guys forget to call the thread pool after using theshutdown(), causing the program to fail to exit properly.

Example: Thread pool not closed

ExecutorService executor = (5);
(() -> ("Task execution in progress...")) ;
// The thread pool is not closed, the program keeps running

The right way to close

();
try {
    if (!(60, )) {
        ();
    }
} catch (InterruptedException e) {
    ();
}

5. Ignoring rejection tactics

When the task queue is full, the thread pool triggers the denial policy, and many people are unaware of the default policy (AbortPolicy) will just throw an exception.

Example: Task rejected

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    1,
    1,
    60L,
    ,
    new ArrayBlockingQueue<>(2),
    new () // default policy
);

for (int i = 0; i < 10; i++) {
    (() -> ("mandates"));
}

The fourth task throws theRejectedExecutionException

Improvement: choosing the right strategy

  • CallerRunsPolicy: The thread that submitted the task executes it itself.
  • DiscardPolicy: Discard the new task directly.
  • DiscardOldestPolicy: Discard the oldest tasks.

6. Exceptions not addressed in the mandate

When a task in the thread pool throws an exception, the thread pool doesn't throw it directly, causing many problems to be overlooked.

Example: Exception Ignored

(() -> {
    throw new RuntimeException("mission anomaly");
});

cure

  1. Catch task internal exceptions:
(() -> {
    try {
        throw new RuntimeException("mission anomaly");
    } catch (Exception e) {
        ("Catching exceptions:" + ());
    }
});
  1. Custom thread factories:
ThreadFactory factory = r -> {
    Thread t = new Thread(r);
    ((thread, e) -> {
        ("threading exception:" + ());
    });
    return t;
};

I recently spent the last year or so putting together my years ofTechnical Growth PathIt's all sunk in and is well worth a look.

Contains:real-world project, stepping pit sharing, source code interpretation, learning route, system design, technology selection, underlying principles, high frequency interview questions, there is everything inside.

7. Blocking tasks from occupying the thread pool

If the tasks in the thread pool are blocking (e.g., file reads and writes, network requests), the core threads will be full, affecting performance.

Example: Blocking Tasks Drag Down the Thread Pool

(() -> {
    (10000); // Simulate a blocking task
}).

Improved methodology

  • Reduce the blocking time of tasks.
  • Increase the number of core threads.
  • Use asynchronous non-blocking methods (e.g. NIO).

8. Abuse of the thread pool

Thread pools are not foolproof, and certain scenarios use directnew Thread() Simpler.

Example: Overuse of Thread Pools

A simple short-term task:

ExecutorService executor = ();
(() -> ("Execute task"));.
();

In this case, it's rather complicated to use a thread pool.

Modalities for improvement

new Thread(() -> ("Execute task")).start();

9. Unmonitored thread pool status

Many people use thread pools and then don't monitor their status, leading to ignored problems with task stacking and thread exhaustion.

Example: Monitoring Thread Pool Status

("Number of Core Threads: " + ());
("Queue size: " + ().size());
("Number of completed tasks:" + ()); ("Number of tasks completed:" + ()).

Combined with monitoring tools (e.g. JMX, Prometheus), real-time monitoring is realized.

10. Dynamic adjustment of thread pool parameters

Some people ignore the need for parameter tuning during thread pool design, leading to difficulties in optimizing performance at a later stage.

Example: Dynamically adjusting the number of core threads

(20);
(50);

Real-time adjustment of thread pool parameters, can adapt to dynamic changes in business.

summarize

Thread pools are powerful tools, but they are also very easy to step into if we don't use them well in our daily work.

In this article, through actual code examples, we can clearly see what the problem with thread pooling is and how to improve it.

Hopefully, this content will help you avoid stepping on potholes and write quality thread pool code!

Thread pool used well, the efficiency of the bar; used poorly, the program crashes every day!

One final note (ask for attention, don't patronize me)

If this article is helpful to you, or inspired, help pay attention to my eponymous public number: Su San said technology, your support is my biggest motivation to keep writing.

Ask for a one-click trifecta: like, retweet, and watch at.

Concerned about the public number: [Su San said technology], in the public number reply: into the big factory, you can get free access to my recent organization of 100,000 words of the interview dictionary, a lot of partners rely on this dictionary to get a number of big factory offers.