SimpleThreadPool

本文介绍了一个简单的JDK1.5线程池实现,包括如何控制任务队列的大小和查看队列剩余任务数等功能。
package com.util;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;


import org.apache.log4j.Logger;


/**
 * jdk1.5线程池的简单实现,可以控制任务队列的大小,也可以查看队列的剩余任务数等情况
 *
 */
public class SimpleThreadPool extends ThreadPoolExecutor {


private Logger log = Logger.getLogger( getClass());

private AtomicInteger taskBalance = new AtomicInteger(0);


private int queueCapacity = 100;


/**
* 构造线程池
* @param corePoolSize 核心线程数
* @param maximumPoolSize  最大线程数
* @param keepAliveTime 非核心线程空闲时间
* @param unit 非核心线程空闲时间单位
* @param workQueue 任务队列
*/
public SimpleThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}


/**
* 构造线程池
* @param corePoolSize 核心线程数
* @param maximumPoolSize  最大线程数
* @param keepAliveSecond 非核心线程空闲时间(单位:秒)
* @param workQueue 任务队列
*/
public SimpleThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveSecond, BlockingQueue<Runnable> workQueue ) {
super(corePoolSize, maximumPoolSize, keepAliveSecond, TimeUnit.SECONDS, workQueue );
}


/**
* 构造线程池
* @param corePoolSize 核心线程数
* @param maximumPoolSize  最大线程数
* @param keepAliveSecond 非核心线程空闲时间(单位:秒)
*/
public SimpleThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveSecond ) {
super(corePoolSize, maximumPoolSize, keepAliveSecond, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
}


/**
* 构造单线程的线程池
* @param workQueue 任务队列
*/
public SimpleThreadPool(BlockingQueue<Runnable> workQueue ) {
super(1, 1, 1, TimeUnit.SECONDS, workQueue );
}

/**
* 构造单线程的线程池
*/
public SimpleThreadPool() {
super(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
}


/**
* 构造单线程的线程池
*/
public static SimpleThreadPool createSingleThread() {
return new SimpleThreadPool();
}


protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
taskBalance.decrementAndGet();

if( log.isDebugEnabled() )
log.debug("task : " + r.getClass().getSimpleName() +  " completed,Throwable:" + t + ",taskBalance:" + getTaskBalance() );

synchronized(this) {
notifyAll();
}
}

public void execute( Runnable task) {
taskBalance.getAndIncrement();
super.execute( task );
}


/**
* 在等待队列未满的情况下,向线程池添加一个任务
* @param task 待执行的任务
* @return 如果队列满,返回false,否则返回true
*/
public boolean addTask( Runnable task) {
if (queueCapacity < getQueue().size() ) {
log.warn("task Queue full!");
return false;
} else {
execute( task );
}
return true;
}


/**
* @return 未执行的任务数
*/
public int getTaskBalance() {
return taskBalance.get();
}

/**
* @param capacity 要设置的队列容量
*/
public void setQueueCapacity(int capacity) {
this.queueCapacity = capacity;
}

public void setMaxPoolSize(int size) {
super.setMaximumPoolSize(size);
}


/**
* @param time 非核心线程可空闲的秒数
*/
public void setKeepAliveSecond(int time) {
super.setKeepAliveTime(time, TimeUnit.SECONDS);
}


/**
* 挂起当前线程,知道所有的任务都执行完成
*/
public void waitCompleted(){
try {
synchronized( this ){
while( getTaskBalance() > 0 ){
wait( 500 );
}
}
} catch (InterruptedException iex) {}
log.info("taskBalance: "+ getTaskBalance() );
}


}

转载于:https://www.cnblogs.com/yangjin-55/archive/2012/11/15/2786618.html

//-------------------------------------------------------------------- // SimpleThreadPool.cpp. // 08/20/2025. created. // 08/20/2025. last modified. //-------------------------------------------------------------------- #include "SimpleThreadPool.h" #include <thread> // 线程库 //-------------------------------------------------------------------- // 初始化静态成员变量(类外初始化) //-------------------------------------------------------------------- std::shared_ptr<SimpleThreadPool> SimpleThreadPool::_thread_pool; std::mutex SimpleThreadPool::_singleton_mx; //-------------------------------------------------------------------- // 单例模式:获取智能指针形式的实例(双重检查锁定,线程安全) inline std::shared_ptr<SimpleThreadPool> SimpleThreadPool::instance_ptr(void) { // 第一次检查:避免每次调用都加锁(提高效率) if (!_thread_pool) { // 加锁:确保多线程下只有一个线程创建实例 std::unique_lock lck{ _singleton_mx }; // 第二次检查:防止加锁期间已有线程创建了实例 if (!_thread_pool) // 创建实例,并指定自定义删除器 _thread_pool.reset(new SimpleThreadPool, &SimpleThreadPool::deleter); } return _thread_pool; } //-------------------------------------------------------------------- // 单例模式:获取引用形式的实例(通过智能指针间接获取SimpleThreadPool& SimpleThreadPool::instance(void) { return *instance_ptr(); } //-------------------------------------------------------------------- // 销毁单例实例(通过重置智能指针释放资源) void SimpleThreadPool::destroy_instance() { if (_thread_pool) { _thread_pool = nullptr; // 智能指针计数归零,触发deleter删除实例 } } //-------------------------------------------------------------------- // 向任务队列添加任务 void SimpleThreadPool::add_task(std::shared_ptr<ISimpleThreadTask> task) { // 忽略空任务 if (!task) return; // 加锁保护任务队列,防止并发修改 std::unique_lock lck{ _task_access_mx }; // 将任务加入队列尾部 _task_queue.emplace_back(task); // 如果当前活跃线程数小于最大线程数,唤醒一个线程处理任务 if (_alive_num < _Max_Num) { _sema.release(); // 信号量计数+1,唤醒一个等待的线程 ++_alive_num; // 活跃线程数+1 } } //-------------------------------------------------------------------- // 构造函数:创建固定数量的工作线程(10个) SimpleThreadPool::SimpleThreadPool() { // 创建10个工作线程(与_Max_Num一致) for (int i = 0; i < 10; ++i) { // 创建线程并立即 detach(脱离主线程控制,后台运行) std::jthread([this](void) -> void { // 线程主循环:持续等待并处理任务 while (true) { // 等待信号量(若计数为0则阻塞,否则计数-1并继续) _sema.acquire(); // 若线程池已标记退出,当前线程退出 if (_is_exit) { --_alive_num; // 活跃线程数-1 break; } // 循环处理任务队列中的所有任务 while (_task_queue.size() > 0) { // 加锁获取任务 std::unique_lock lck{ _task_access_mx }; // 再次检查队列(防止解锁期间任务被其他线程取完) if (_task_queue.size() > 0) { // 取出队列头部的任务 auto task = _task_queue.front(); _task_queue.pop_front(); // 从队列移除任务 lck.unlock(); // 提前解锁,避免执行任务时占用锁 // 执行任务 task->run_task(); } } // 任务处理完毕,活跃线程数-1 --_alive_num; } }).detach(); } } //-------------------------------------------------------------------- // 析构函数:(目前为空,可扩展为设置退出标志唤醒所有线程) SimpleThreadPool::~SimpleThreadPool() {} //-------------------------------------------------------------------- // 自定义删除器:销毁线程池实例(智能指针释放时调用) void SimpleThreadPool::deleter(SimpleThreadPool* p) { if (p) { delete p; // 调用析构函数 } } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // SimpleThreadPool.h. // 08/20/2025. created. // 08/20/2025. last modified. //-------------------------------------------------------------------- #pragma once #include <memory> // 智能指针 #include <semaphore> // 信号量(C++20) #include <mutex> // 互斥锁 #include <list> // 任务队列(链表) #include <vector> #include "ISimpleThreadTask.h" // 任务接口 //-------------------------------------------------------------------- // 线程池类:单例模式,管理固定数量的工作线程和任务队列 class SimpleThreadPool { public: // 获取单例的智能指针 static std::shared_ptr<SimpleThreadPool> instance_ptr(void); // 获取单例的引用 static SimpleThreadPool& instance(void); // 销毁单例实例 static void destroy_instance(); // 向线程池添加任务(接受任务接口的智能指针) void add_task(std::shared_ptr<ISimpleThreadTask> task); //批量添加任务) // void add_task(std::vector<std::shared_ptr<ISimpleThreadTask>> tasks); private: // 私有构造函数(单例模式禁止外部创建) SimpleThreadPool(); // 私有析构函数(单例模式禁止外部销毁) ~SimpleThreadPool(); // 禁止拷贝构造和移动构造(单例模式唯一性保证) SimpleThreadPool(SimpleThreadPool const&) = delete; SimpleThreadPool(SimpleThreadPool&&) noexcept = delete; // 自定义删除器(供智能指针销毁实例时调用) static void deleter(SimpleThreadPool* p); private: // 最大工作线程数(固定为10) constexpr static long long _Max_Num{ 10 }; // 单例实例(智能指针管理) static std::shared_ptr<SimpleThreadPool> _thread_pool; // 单例创建的互斥锁(防止多线程同时创建实例) static std::mutex _singleton_mx; // 信号量:控制工作线程的唤醒(最大计数为_Max_Num) std::counting_semaphore<_Max_Num> _sema{ 0 }; // 任务队列:存储待执行的任务(链表适合频繁增删) std::list<std::shared_ptr<ISimpleThreadTask>> _task_queue; // 任务队列的互斥锁(保护队列的并发访问) std::mutex _task_access_mx; // 当前活跃的工作线程数(正在执行任务或被唤醒的线程) long long _alive_num{ 0 }; // 线程池退出标志(用于通知工作线程退出) bool _is_exit{ false }; }; //-------------------------------------------------------------------- //-------------------------------------------------------------------- // ISimpleThreadTask.h. // 08/20/2025. created. // 08/20/2025. last modified. //-------------------------------------------------------------------- #pragma once // 防止头文件重复包含 //-------------------------------------------------------------------- // 线程任务接口类:所有线程池任务必须继承此类并实现run_task方法 class ISimpleThreadTask { public: // 纯虚函数:任务执行的入口,子类需实现具体逻辑 virtual void run_task(void) = 0; }; //-------------------------------------------------------------------- #include <iostream> #include "SimpleThreadPool.h" #include <chrono> // 时间相关函数 using namespace std::chrono_literals; // 简化时间单位(如1s、100ms) // 自定义任务类:继承任务接口,实现具体任务 class CustomTask : public ISimpleThreadTask { public: CustomTask(int v) : _v{ v } {} // 构造函数:传入任务编号 // 实现任务执行逻辑 void run_task(void) override { std::wcout << L"CustomTask: " << _v << std::endl; // 打印开始信息 std::this_thread::sleep_for(1s); // 模拟任务耗时1秒 std::wcout << L"CustomTask Exit: " << _v << std::endl; // 打印结束信息 } private: int _v; // 任务编号(用于区分不同任务) }; int main(void) { // 向线程池添加50个任务 for (int i = 1; i <= 50; ++i) { // 创建CustomTask实例(智能指针管理),添加到线程池 SimpleThreadPool::instance_ptr()->add_task( std::shared_ptr<CustomTask>(new CustomTask(i))); } // 休眠60秒:等待所有任务执行完毕(实际应根据任务完成状态判断) std::this_thread::sleep_for(60s); // 销毁线程池实例 SimpleThreadPool::destroy_instance(); return 0; }给我讲一下这几段代码 这就是设计了一个线程池 我现在要根据他做笔记
08-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值