Deep Thoughts on Thread Pool Interview No. 3: Threads

6 Threads (Alibaba Healthy Two Faces)

6.1 What is the relationship between the number of threads in your thread pool and the number of tables?

Answer: What I thought at the time was to set the number of core threads to 20. This is based on the formula (number of core threads = number of cpu cores (thread waiting time/average time for thread execution tasks + 1)). The maximum number of threads is set in the table. , and then use a blocking queue. The number of non-core threads here does not dare to be set too large, because data synchronization involves a large number of data migration tasks, so if too many data are pulled from mysql at the same time during the synchronization process, data, may cause OOM;

If the amount of table data to be synchronized is basically small, and the subsequent modification operation is performed, it is better to use cachedThreadPool for the synchronization operation.

6.2 If it is an IO-intensive requirement, the CPU idle time will be very long. How to design a thread pool better?

Because this is an IO-intensive requirement, the IO time of a task is very long, which means that it will be blocked during network IO and the CPU idle time will be very long.

For IO-intensive tasks, since threads do not consume CPU while waiting for IO (for example, disk operations or network requests), more threads can be used to improve system throughput. However, threads themselves are not free as they require memory (e.g., thread stack) and add thread scheduling overhead. Therefore, the number of threads cannot be too many.

Here are some suggestions for designing thread pools for IO-intensive needs:

  1. Thread number setting :

    • You can consider setting the number of threads relatively large, a common strategy is CPU核数 * 2or higher.
    • You can also consider dynamically adjusting the number of threads based on the ratio of the system's actual IO waiting time and CPU time.
  2. Choose the appropriate queue :

    • Using a bounded queue, for example ArrayBlockingQueue, can prevent tasks from being backlogged and causing memory overflow.
    • Reasonably select the queue size based on the actual business load. A queue that is too large may consume more memory, and a queue that is too small may cause too many tasks to be rejected.
  3. Thread survival time :

    • For IO-intensive tasks, the thread survival time can be set relatively short, so that thread resources that are no longer needed can be released faster.
  4. Deny policy :

    • When the queue is full and the number of threads reaches the maximum, a strategy is needed to handle incoming tasks. The default strategy is to throw RejectedExecutionException, but you can also choose other strategies, such as the caller run strategy, allowing the thread that submitted the task to perform the task itself.
  5. Use task priority :

    • If some IO tasks are more urgent than others, consider using a priority queue.
  6. Monitoring and tuning :

    • Monitor key indicators of the thread pool, such as: queue length, number of threads, CPU usage, etc. This information can be used to determine whether the thread pool configuration needs to be adjusted.
    • Adjust the configuration of the thread pool according to business peak periods. For example, when IO demand is low at night, the number of threads can be reduced.

In summary, for IO-intensive requirements, the main goal is to maximize system throughput. This usually means using more threads and configuring the parameters of the thread pool appropriately.

6.3 When do you think the threads in the thread pool were created?

Answer: The core thread can be created when the thread pool is declared. This is equivalent to thread preheating. The task can be used as soon as it comes. This is controlled by the preStart parameter.

6.4 What do you think the status of a thread is?

Answer: running, ready, blocked, terminated

In Java, the life cycle of a thread includes multiple states. The following are the main states of Java threads:

  1. New (NEW) :

    • The thread is in this state when we create a thread object but have not yet called its start()methods.
  2. Runnable (RUNNABLE) :

    • start()A thread object is in a runnable state when its method has been called , but the thread scheduler has not yet selected it as the thread of current execution. This also includes the status of threads running inside the Java virtual machine.
  3. BLOCKED :

    • The thread is waiting for the monitor lock (for example, when a thread calls a synchronized method or synchronized block and the current synchronized method or synchronized block is already held by another thread, then the thread enters the BLOCKED state).
  4. Waiting :

    • The thread is in a waiting state because one of the following methods was called:
      • Object.wait()
      • Thread.join()
      • LockSupport.park()
    • This is an unlimited wait, and the thread needs to be explicitly awakened by other threads.
  5. Timeout waiting (TIMED_WAITING) :

    • When a thread calls one of the following methods and specifies a timeout parameter, the thread will be in this state:
      • Thread.sleep(long millis)
      • Object.wait(long timeout)
      • Thread.join(long millis)
      • LockSupport.parkNanos()orLockSupport.parkUntil()
    • A thread remains in this state until the timeout is reached or another thread wakes it up.
  6. TERMINATED :

    • A thread is in this state when its run()method completes or when the thread is interrupted.

In Java programming, you can use Thread.getState()the method to get the current status of a thread. This is very useful for debugging and thread management.

6.5 If you find that the CPU usage is very high, what state of threads will you focus on?

Answer: If the thread is in the blocking state, it should not occupy much CPU and is suspended in the blocking queue, so we should focus on the threads in the running state.

6.6 If I find that the number of threads of an application has been growing slowly, and the number of visits does not fluctuate much at this time, and your CPU and load do not fluctuate much, how will you analyze it and what should you do? How to analyze it in this way, what status of threads will you pay attention to? (I answered incorrectly)

answer:

Answer: When the number of threads of an application continues to grow slowly, but the number of visits, CPU and load are relatively stable, the possible situations are:

  • Thread leakage : Some threads may not be closed properly, causing the number of threads to gradually increase over time . This can happen when using custom threads or thread pools.

  • Third-party library/component : You may be using a library or component that creates threads internally and does not manage them correctly.

For further analysis:

  1. Thread stack analysis : You can use Java's built-in tools jstackto view the application's thread stack. This will give each thread a snapshot showing what the thread is doing. Through this tool, you can identify what the growing thread does and which part of the code is started.

  2. Pay attention to the status : especially the WAITING and TIMED_WAITING threads. Although these threads may not consume a large amount of CPU , they may be blocked waiting for a certain resource or a certain condition, causing the number of threads to grow.

  3. Monitoring tools : Use tools such as VisualVM, JProfiler, etc. to monitor the creation, status, and destruction of threads in real time. This can help identify patterns of thread creation and possible thread leaks.

  4. Log review : Review the application's logs to check for exceptions, errors, or other relevant information, which may be related to the behavior of the thread.

  5. Code review : Check all places in the code where threads or thread pools are created to ensure that threads are shut down properly after completing their tasks.

Conclusion: When the number of threads continues to grow but other indicators are relatively stable, it is likely to be a thread management problem or a thread leak. The key is to find which threads keep being created and why they are not shut down properly.

6.7 How do you understand the horizontal and vertical aspects of the flame graph? Can it solve the problem I just mentioned?

Answer: Horizontally, it represents the CPU time spent when executing a thread, and vertically, it represents the call stack of the method. Because what you just said is that the thread does not occupy the CPU very much, that is, the task may be executed but not released correctly, so the flame graph is not applicable. to solve this problem

Guess you like

Origin blog.csdn.net/yxg520s/article/details/132847187