JAVA concurrent system 1.4-thread pool

In any thread pool, the existing thread where possible, will be automatically reused.

introduction

Rational use of the thread pool can bring three benefits

  1. Reduce resource consumption . By reusing the thread has been created to reduce thread creation and destruction caused by consumption.
  2. Improve the response speed . When the mission arrives, the task may not need to wait until the thread creation can be implemented immediately.
  3. Improve threads manageability . A thread is a scarce resource, if the unlimited creation, not only consumes system resources, but also reduce the stability of the system, using a thread pool can be unified distribution, tuning and monitoring. But to be a reasonable use of the thread pool must be well aware of its principle.

Inheritance system

Inheritance system thread pool:

todo: Change this figure (ie without using screenshots)

Actuator Executor

Executor is the preferred method of starting the task, will manage the Executor Thread object, and command design patterns ( TODO: ?? not appreciate ?? ), he exposes a single method to be executed. Executor provided a mechanism (decoupling) to leave the "mission submission" and "mandate" points.

public class CachedThreadPool {
    public static void main(String[] args){
        ExecutorService exec = Executors.newCachedThreadPool(); // 创建
        for(int i=0;i<5;i++);
        	exec.execute(new Liftoff); // 执行
        exec.shutdown();// 终止全部
    }
}

Calls on shutdown can prevent the new task is submitted to the executor, the current thread (the main thread in this case) will continue to run all tasks submitted before the shutdown is called, the program will exit as soon as possible after the completion of all tasks executor.

Thread Pool

Constructor / core parameters

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                   TimeUnit unit, BlockingQueue<Runnable> workQueue,
                   ThreadFactory threadFactory, RejectedExecutionHandler handler)
  • corePoolSize(Basic thread pool size) (core number of threads):

    When submitting a task to the thread pool , the thread pool will create a thread to perform the task, even if the other free basic thread can perform new tasks will be to create a thread, until the number of tasks need to be performed is greater than the thread pool size is no longer essential to create .

    If the thread pool calls the prestartAllCoreThreadsmethod, the thread pool will be created in advance and start all basic threads.

  • maximumPoolSize(Maximum thread pool size):

    The maximum number of thread pool threads can be created. If the queue is full, and the number of threads that have been created less than the maximum number of threads, the thread pool will re-create a new thread to perform the task.

    It is worth noting that if you use unbounded task queue this parameter to no effect.

  • keepAliveTime(Thread activity hold time):

    • After the thread pool worker thread is idle, keeping alive the time. So if a lot of tasks, and each task execution time is relatively short, it can turn up this time, improve the utilization of the thread.

    • The current number of threads is greater than the core number of threads, if the idle time has been exceeded keepAliveTime, then the thread will be destroyed . todo: ??

  • TimeUnit(Thread activity to maintain unit time):

    Optional units day (DAYS), h (HOURS), min (MINUTES), ms (MILLISECONDS), microsecond (MICROSECONDS, thousandth ms) and ns (nanoseconds, microseconds thousandth) .

  • workQueue(Task queue):

    Save waiting for task execution queue blocking. When you reach corePoolSizethe time, just to put in the waiting queue thread information (as a default LinkedBlockingQueue), the thread running properties as: workers, into one HashSet; our internal Runnable was packed layer; this is a default queue unbounded queue ( you can also set a bounded queue), so when the producers crazy production, it is necessary to consider the question of how to control.

  • threadFactory(Thread factory):

    For creating a thread factory setting, very helpful when you can set more meaningful to each created by a thread factory out of the thread name, Debug and positioning issues.

  • handler(Saturation strategy) (denial policy):

    When the queue and thread pools are full, indicating that the thread pool is saturated, it must adopt a strategy to deal with the new task submission.

About workQueueyou can choose from several blocking queue

  1. ArrayBlockingQueue: It is based on an array configuration bounded blocking queue This queue FIFO (first in first out) principle sort elements.
  2. LinkedBlockingQueue: Based on a linked list structure blocking queue This queue FIFO (First In First Out) collating element, throughput is usually higher than ArrayBlockingQueue. Static factory method Executors.newFixedThreadPool()to use this queue.
  3. SynchronousQueue: A blocking queue element is not stored. Each insert operation must wait until another thread calls the removal operation, or insert operation has been in a blocked state, throughput is usually higher than LinkedBlockingQueuethe static factory method Executors.newCachedThreadPoolto use this queue.
  4. PriorityBlockingQueue: A prioritized infinitely blocking queue.

Namely: TODO: and above difference? ?

  • Synchronous transfer: do not put in the queue, but the waiting thread to execute it . If the current thread is not performed, it is likely to open a thread.
  • No limit strategy: if the core threads are working, the thread will be placed in the queue . Therefore, no more than the number of threads core threads
  • There are limits strategy: avoid resource exhaustion , but to some extent reduced the throughput

Four kinds handler(saturation strategy) (denial policy)

  1. CallerRunsPolicy: Where only the caller thread to run the task.
  2. DiscardOldestPolicy: Discard queue recent task and execute the current task.
  3. DiscardPolicy: No treatment, discarded.
  4. Of course, depending on the application may be required to implement scenario RejectedExecutionHandlerinterface to the custom policy. Such as logging or persistence task can not handle.

Namely: TODO:? ? ? And the difference between above 4

  • Direct throw an exception
  • Use the caller's thread to handle
  • Lose the direct task
  • Discard the oldest task

Submit jobs

Use the execute method, submit method, corresponding to a Runnable, Callable, corresponding statement venue article threads and tasks .

execute workflow

When creating a thread pool thread, the thread will be packaged into a worker thread Worker, Worker after performing the task, the work will get an infinite loop queue of tasks to perform.

When submitting a new task to the thread pool thread pool process is as follows:

  1. First thread pool to determine the basic / core thread pool is full? Not full, create a worker thread to perform tasks. Full, then enter the next process.
  2. Secondly thread pool to determine the work queue is full? Not full, the task will be stored in the newly submitted job queue. Full, then enter the next process.
  3. The last thread pool to determine the entire thread pool is full? Not full, then create a new worker thread to perform the task, it is full, to the saturation of any strategy to deal with this

which is:

  • If the number of running threads is less than the number of kernel threads, create new threads to process the request
  • If the number of running threads is greater than the core number of threads, it is less than the maximum number of threads, when the queue is full when it is creating a new thread
  • If the number of kernel threads equal to the maximum number of threads, it will create a fixed size of the connection pool
  • If you set the maximum number of threads is infinite , then the thread pool allows for any number of concurrent

todo: Pictured right to modify these two map

Close the thread pool

The calling thread pool shutdownor shutdownNowmethod to close the thread pool, after calling these two methods will return immediately back from the process without waiting thread pool is closed .

  • shutdown

    • The principle : only the state of the thread pool is set to SHUTDOWN state, and then not being interrupted all threads mission.
    • Only tell executor service it can not accept new tasks , but the task has been submitted will continue to run
      • Submit again the thread pool task will throw RejectedExecutionExceptionan exception
    • No return value
    • If the thread pool shutdown () method has been called, repeated calls no additional effect
  • shutdownNow

    • The principle : First, the state of the thread pool is set to STOP, then traverse the thread pool worker thread, and then one by one thread calls the interrupt method to interrupt the thread, the thread of all attempts to stop or pause the task being performed, and returns awaiting execution task list of.
    • Since the call interrupt method, it can not respond to interrupt interrupted task may never terminate .
    • Return value: For those tasks waiting to be executed congestion queue , the thread pool will not go to perform these tasks, but directly back to these tasks waiting to be executed
    • shutdownNowWhen the call:
      • If the thread is blocked state, the thread immediately exit the blocked state, and throws an InterruptedExceptionexception.
      • If the thread is in normal working condition, the interrupt flag is set to true, the thread will continue unaffected
    • About interrupt interrupt, please move the article end tasks or threads

isShutdownwithisTerminaed

  • As long as two close calls this method one, isShutdownthe method returns true.

  • When all the tasks have been closed, it indicates that the thread pool is closed successfully, then call the isTerminaedmethod returns true.

As for which way we should call to close the thread pool should be determined by the characteristics of the task to submit to the thread pool, usually calls shutdownto close the thread pool, if you do not have to perform the task complete (may be suddenly interrupted when there is no congestion), you can call shutdownNow.

Thread Pool Monitor

Parameters monitored by the thread pool provided . There are some thread pool attributes can be used to monitor the thread pool when

  • taskCount: The number of tasks you need to perform the thread pool.
  • completedTaskCount: The number of tasks in the thread pool during operation has been completed. Less than or equal taskCount.
  • largestPoolSize: The maximum number of threads in the thread pool has been created before. Through this data to know whether the thread pool is too full. As equal to the maximum size of the thread pool, then the thread pool once full.
  • getPoolSize: The number of threads in the thread pool. If the thread pool is not destroyed, then thread pool does not automatically destroyed, so this size only to rise.
  • getActiveCount: The number of threads access activities.

Monitored by extending the thread pool . By inheriting the thread pool thread pool and rewrite beforeExecute, afterExecuteand terminatedmethods, we can perform the task before, after and before the implementation of the thread pool is closed to do some things. If the average execution time monitoring tasks, the maximum execution time and minimum execution time. These methods in the thread pool is empty, such as:

protected void beforeExecute(Thread t, Runnable r) { }

Common thread pool

  • newFixedThreadPool(int nThreads)
    • Create a limited set of threads, a one-time pre-execution thread allocation costly, do not have to pay each task a fixed overhead of creating a thread.
  • newCachedThreadPool()
    • Typically create the same number of threads required during program execution, then stopped when he recovered the old thread creates a new thread.
  • newSingleThreadExecutor()
    • As is the number of threads 1FixedThreadPool
    • For want of anything continuous operation in another thread ( long-term survival of the task ), it is useful (for example: Strategy: listen for incoming socket connection task that is serversocketrunning short tasks such as updating a local or remote log small task or event dispatch thread)
    • To SignalThreadExecutorsubmit more than one task queue ; and SignalThreadExecutorprovides an important guarantee concurrency, other threads will not be invoked concurrently, which would change the lock demand tasks , such as: Strategy: Use SignalThreadExecutorto run requires a lot of threads to access the file system, in this manner, the shared resources do not need the synchronization process (using a file system is not excessively)

Executor create each type of thread pool are additionally contains a constructor, add an additional parameter on the basis of common construction methods, namely ThreadFactory threadFactory, for example newSingleThreadExecutor(ThreadFactory threadFactory).

There are also some interesting thread pools: newWorkStealingPool(), newSingleThreadScheduledExecutor(),newScheduledThreadPool(int corePoolSize)

⭐️ rational allocation of thread pool

To a reasonable allocation of the thread pool, you must first analyze task characteristics you to select different thread pool based on the different types of tasks. In order to avoid additional support full system memory, improve system stability and capacity warning should be used bounded queue (queue bounded warning to increase the stability and capacity of the system can be set larger as needed, such as thousands).

By taking the task split, different sizes of thread pool to handle different types of tasks, bounded queue to improve efficiency.

It can be done from the perspective of the following analysis tasks characteristics :

  1. Nature of the tasks: the CPU-intensive task, IO-intensive tasks and mixed tasks.
  2. Task priority : high, medium and low.
  3. Task execution time : long, medium and short.
  4. Task -dependent : if dependent on other system resources , such as database connections .

For tasks with different characteristics, can the measures taken are:

  • CPU-intensive task configuration minimal number of threads, such as threads disposed Ncpu + 1 thread pool (Ncpu: cpu number).

  • IO-intensive task due to the need to wait for IO operations, the thread is not always on a mission, then configure as many threads as 2 * Ncpu.

  • Mixed task if can be split, it is split into a CPU intensive task and a task-intensive IO

    • Two task execution time difference is not too large, the throughput is executed after decomposition throughput than serial execution ,
    • Two task execution time difference is too large, it is not necessary for decomposition.
  • Different priority task can use the priority queuePriorityBlockingQueue for processing. It allows high-priority task to be implemented, should be noted that if there has been a high priority task submitted to the queue, then the low priority task may never execute .

  • Different execution time of the task can be handed over to different sizes of thread pool to handle, or you can use the priority queue , so that the execution time is short before the task execution.

  • Dependent tasks database connection pool , because of the need to wait for the thread to submit SQL database returns the results, if you wait the longer CPU idle longer time, then the number of threads should be set greater , so as to make better use of CPU.

reference

  1. Chapter reciprocal Fourth Edition Java programming ideas Chinese version
  2. Analysis and use of concurrent chat (c) Java thread pool

Guess you like

Origin www.cnblogs.com/cheaptalk/p/12549674.html