线程池添加工作线程的流程
时间: 2023-07-24 07:16:22 浏览: 120
线程池添加工作线程的流程如下:
1. 当有任务提交到线程池时,线程池会首先检查当前活动线程数(即已创建的线程数)是否小于核心线程数(corePoolSize)。
2. 如果活动线程数小于核心线程数,则线程池会创建一个新的工作线程来执行任务。新创建的线程会被启动并开始执行任务。
3. 如果活动线程数已经达到核心线程数,则任务会被放入阻塞队列(workQueue)中等待执行。
4. 如果阻塞队列已满,并且活动线程数还未达到最大线程数(maximumPoolSize),则线程池会创建额外的工作线程来执行任务。
5. 如果活动线程数已经达到最大线程数,并且阻塞队列也已满,此时线程池会根据拒绝策略(rejectedExecutionHandler)来处理无法接受的新任务。
6. 当工作线程执行完任务后,如果空闲时间超过了空闲线程存活时间(keepAliveTime),且当前活动线程数超过核心线程数,那么多余的空闲线程会被回收销毁,以减少资源消耗。
通过动态创建和回收工作线程,线程池可以根据任务的数量和系统资源情况来灵活管理和调整线程数量,以提高线程池的效率和性能。
相关问题
c++设计线程池类启用单个线程的流程以及示例
启用单个线程的线程池类示例代码如下:
```cpp
#include <iostream>
#include <thread>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
class ThreadPool {
public:
ThreadPool() : stopped(false) {}
~ThreadPool() {
stop();
}
void enqueue(std::function<void()> task) {
{
std::unique_lock<std::mutex> lock{mutex};
tasks.push(task);
}
condition.notify_one();
}
void start() {
for (int i = 0; i < 1; ++i) {
workers.emplace_back([this] {
while (true) {
std::unique_lock<std::mutex> lock{mutex};
while (!stopped && tasks.empty()) {
condition.wait(lock);
}
if (stopped && tasks.empty()) {
return;
}
auto task = tasks.front();
tasks.pop();
lock.unlock();
task();
}
});
}
}
void stop() {
{
std::unique_lock<std::mutex> lock{mutex};
stopped = true;
}
condition.notify_all();
for (auto& worker : workers) {
worker.join();
}
}
private:
std::queue<std::function<void()>> tasks;
std::vector<std::thread> workers;
std::mutex mutex;
std::condition_variable condition;
bool stopped;
};
int main() {
ThreadPool pool;
pool.start();
pool.enqueue([] {
std::cout << "Hello from task 1!" << std::endl;
});
pool.enqueue([] {
std::cout << "Hello from task 2!" << std::endl;
});
pool.stop();
return 0;
}
```
在这个示例代码中,我们创建了一个 ThreadPool 类,其中包含一个队列用于存储待执行的任务,一个线程池用于执行任务,以及一个互斥锁和条件变量用于同步任务的执行。我们还提供了 enqueue() 方法,用于将任务添加到队列中。在 start() 方法中,我们启动一个单独的线程,该线程不断地从队列中获取任务并执行它们。在 stop() 方法中,我们设置了 stopped 标志,通知所有线程停止执行任务。在主函数中,我们创建了一个 ThreadPool 实例,添加了两个任务,并在程序退出时停止线程池。
需要注意的是,这个示例代码中只启用了一个线程来执行任务。如果需要启用多个线程,只需将 for 循环中的 1 改为需要的线程数即可。
java 线程池工作流程
Java 线程池的工作流程主要包括以下几个步骤:
1. **提交任务(Submit Task)**:当开发者创建一个 `FutureTask` 或者直接提交 `Runnable` 到线程池,比如通过 `ThreadPoolExecutor.execute()` 方法,任务就被添加到线程池的待处理队列中。
2. **调度任务(Schedule Task)**:线程池有一个内部的任务调度机制,会检查待处理队列是否为空。如果没有,就会从队列中取出第一个任务分配给一个空闲的线程去执行。
3. **线程执行(Thread Execution)**:线程开始执行任务,这可能是计算密集型任务,也可能是 I/O 密集型任务,取决于任务的性质。
4. **线程同步(Synchronization)**:多个任务可能会争夺共享资源,线程池内的线程通常会通过内置的同步机制(如 `Semaphore`, `CountDownLatch` 等)保证它们之间的正确协作。
5. **任务完成(Task Completion)**:一旦任务执行完毕,线程会将结果返回,如果是 `FutureTask`,还会调用其 `get()` 方法来获取结果。
6. **线程回收(Thread Recycling)**:线程池会根据配置决定线程的生命周期。如果线程执行完成后仍然有空闲线程,它会被放入线程池继续等待新的任务;如果线程池已满,线程则可能被销毁并重新创建。
7. **拒绝策略(Rejected Policy)**:当线程池达到最大并发数但仍接收到新任务时,会根据线程池的拒绝策略来处理,常见的策略有直接丢弃、循环队列溢出、抛出异常等。
阅读全文