深度解析:Java线程池ThreadPoolExecutor原理与实战

0 下载量 11 浏览量 更新于2024-08-28 收藏 477KB PDF 举报
线程池是多线程编程中的一个重要概念,它允许我们高效地管理多个线程,避免了频繁创建和销毁线程的开销。在Android开发中,理解线程池的原理和使用方法对于优化应用程序性能至关重要。 线程池的核心参数包括以下几个方面: 1. **corePoolSize**:线程池的基本大小,即线程池在没有任务处理时会保持的最小线程数量。 2. **maximumPoolSize**:线程池能容纳的最大线程数量,当工作队列满时,超过corePoolSize的线程会根据这个值来创建。 3. **keepAliveTime**:当线程池内线程数量超过corePoolSize且空闲时,线程存活的最长时间。 4. **unit**:keepAliveTime的时间单位。 5. **workQueue**:用来存储待处理任务的队列,如ArrayBlockingQueue或SynchronousQueue等。 6. **threadFactory**:用于创建新线程的工厂,可以自定义线程的属性,如线程名称、优先级等。 `ThreadPoolExecutor`是Java提供的线程池的实现类,开发者可以根据需求调整这些参数以定制线程池。Java还预定义了四种线程池: - **FixedThreadPool**:定长线程池,只包含核心线程,线程数量固定,任务队列无大小限制,适合处理大量重复性的任务,可以控制并发数量。 - **ScheduledThreadPool**:定时线程池,适用于执行定时或周期性任务,有固定的核心线程数,非核心线程会自动回收。 - **CachedThreadPool**:可缓存线程池,线程数量动态变化,无核心线程,新建线程速度快,适合处理大量短生命周期的任务,但可能导致线程数量过多,消耗资源。 - **SingleThreadExecutor**:单线程化的线程池,所有的任务都在一个线程中按顺序执行,确保任务的执行顺序,适用于需要同步的场景。 使用这些预定义线程池时,可以通过`Executors`类提供的静态方法创建,例如: ```java ExecutorService fixedThreadPool = Executors.newFixedThreadPool(int corePoolSize); ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(int corePoolSize); ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); ``` 在实际应用中,选择合适的线程池类型和配置参数至关重要,这需要根据应用的需求,如并发量、任务类型、资源限制等因素来综合考虑。合理使用线程池不仅可以提高程序执行效率,还能有效防止资源耗尽,避免因线程过多导致的系统崩溃。
2023-05-31 上传

class CustomSysmodel : public QFileSystemModel { Q_OBJECT public: CustomSysmodel(QWidget *parent = Q_NULLPTR) : QFileSystemModel(parent) , m_limit(100) , m_timer(new QTimer(this))//m_timer 使用 this 作为其父对象创建的,在 CustomSysmodel 对象被删除时自动删除(不确定) { connect(m_timer, &QTimer::timeout, this, &CustomSysmodel::loadMoreFiles);//直接在构造函数中植入计时器 m_timer->setInterval(2000); } void CustomSysmodel::fetchFiles(const QString &path) { emit started(); QThread *thread = new QThread; //**********************需要释放空间 FileSystemWorker *worker = new FileSystemWorker; worker->moveToThread(thread); connect(thread, &QThread::started, worker, this, worker, path { worker->fetchFiles(path); }); connect(worker, &FileSystemWorker::fileFound, this, &CustomSysmodel::fileFound); connect(worker, &FileSystemWorker::finished, thread, &QThread::quit); connect(worker, &FileSystemWorker::finished, worker, &FileSystemWorker::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(worker, &FileSystemWorker::finished, this, &CustomSysmodel::finished); thread->start();//启动线程 QMetaObject::invokeMethod(thread, "wait", Qt::QueuedConnection);//另一种写法,还是不能边构建model边描画 delete thread; delete worker; } } class FileSystemWorker : public QObject { Q_OBJECT public: FileSystemWorker(QObject *parent = nullptr) : QObject(parent) {} public slots: void fetchFiles(const QString &path) { QFileInfoList files = QDir(path).entryInfoList(QDir::Files); foreach (const QFileInfo &fileInfo, files) { cout<<"xianc"<<endl; emit fileFound(fileInfo.absoluteFilePath()); } } signals: void started(); void finished(); void fileFound(const QString &filePath); }; 如上述代码所示:qtreeview使用继承自Qfilesystemmodel的自定义模型,想要实现单独线程读取文件,再发送给主线程,目的是为了访问百万级文件时,可以流畅访问。 但现在只有全部加载完主线程才能运行,分析原因,给出完整的修改方案

2023-05-31 上传
2023-05-31 上传

class CustomSysmodel : public QFileSystemModel { Q_OBJECT public: CustomSysmodel(QWidget *parent = nullptr) : QFileSystemModel(parent) , m_limit(100) , m_timer(new QTimer(this)) , m_threadPool(new QThreadPool(this)) { connect(m_timer, &QTimer::timeout, this, &CustomSysmodel::loadMoreFiles); m_timer->setInterval(2000); } public slots: void fetchFiles(const QString &path) { emit started(); FileSystemWorker *worker = new FileSystemWorker(path); connect(worker, &FileSystemWorker::fileFound, this, &CustomSysmodel::fileFound); connect(worker, &FileSystemWorker::finished, this, &CustomSysmodel::finished); m_threadPool->start(worker); } private slots: void loadMoreFiles() { int rowCount = this->rowCount(); int diff = m_filePaths.size() - rowCount; if (diff > 0) { beginInsertRows(QModelIndex(), rowCount, rowCount + diff - 1); for (int i = rowCount; i < rowCount + diff && i < m_limit; i++) { QFileInfo fileInfo(m_filePaths.at(i)); QFileSystemModel::fetchMore(QFileSystemModel::index(fileInfo.path())); } endInsertRows(); } } signals: void started(); void finished(); void fileFound(const QString &filePath); private: int m_limit; QTimer *m_timer; QThreadPool *m_threadPool; }; class FileSystemWorker : public QObject, public QRunnable { Q_OBJECT public: FileSystemWorker(const QString &path, QObject *parent = nullptr) : QObject(parent) , m_path(path) { } void run() override { QFileInfoList files = QDir(m_path).entryInfoList(QDir::Files); foreach (const QFileInfo &fileInfo, files) { emit fileFound(fileInfo.absoluteFilePath()); } emit finished(); } signals: void started(); void finished(); void fileFound(const QString &filePath); private: QString m_path; }; 文件加载页面只有等全部文件加载完才能运行,分析原因,给出修改方案

2023-05-31 上传
2023-05-31 上传