池的概念在任何计算机语言中是一个非常重要的思想,任何事情都是有因果的,没有无缘无故的技术,总是为了解决什么问题而出现的。
池的概念就是为了解决资源有限而需求无限的问题。人总是贪婪的,所以总是想占有最多最好的资源,但是人是社会性的,所以需要跟大伙共享一些公共资源,那如何解决这个资源分配的问题呢?
首先资源分配总的原则应该是公平合理高效。翻开经济学的定义,
经济学是一个社会如何利用稀缺的资源生产有价值的物品和劳务,并将它们在不同的人中间进行分配。
为什么
回到线程池,首先,为什么线程是有限资源?
第一线程可以很多,为什么有很多,因为要同时做两件事情嘛,而且做一件事情的时候可能需要等待的时间或者在多核CPU的情况下,因此为了不浪费时间或者为了充分利用多核的硬件,我们就在提出了多线程的概念。
那为什么线程的多少有限呢?应该说java里面线程可以随便创建,关键是创建需要时间,销毁也相当耗时间,就像我要吃饭这个事情,非要让我在去吃饭的路上花很多时间一样,完全喧宾夺主啊。
因此我们把这些公共的创建线程,销毁线程的动作放在一个池里面,让池来预先帮我们做好这些事情,这样不就大大提高了执行的效率了吗?
而且这种集中式的管理,对于监控带来了极大的优点。这就是小动作大力量啊。
怎么做
首先,我们需要一个池,我叫它ThreadPool
其次,需要线程,我叫它WorkThread
其它的就是一些增强的功能,比如我定义的Tracker用来监控每个任务执行的情况和ThreadPoolContainer用来包含和组织这些动作。
核心代码如下:
ThreadPool
private static ArrayList<WorkThread> allThreads=new ArrayList<WorkThread>();
private LinkedBlockingQueue<WorkThread> freeThreads=new LinkedBlockingQueue<WorkThread>();
public synchronized boolean notifyOnNewTask(Runnable cmd) {
WorkThread temp=null;
while((temp=freeThreads.poll())!=null){
if(temp.canWork()){
temp.addTask(cmd);
return true;
}//if not free, go to next thread
}
while(allThreads.size()<maxSize){
WorkThread thread=new WorkThread(this,groupName+allThreads.size(),isDaemon);
allThreads.add(thread);
thread.start();
if(thread.canWork()){
thread.addTask(cmd);
return true;
}
}
waitingQueue.add(cmd);
return false;
}
//free a thread
public synchronized void addToFreeList(WorkThread workThread) {
Runnable cmd=waitingQueue.poll();
if(cmd!=null){//no need to add to free list, who is free, who will do the job.
workThread.addTask(cmd);
return;
}
if(!freeThreads.contains(workThread)){
freeThreads.add(workThread);
}
}
WorkThread
public void run() {
while (isUp) {
isFree.set(true);
m_pool.addToFreeList(this);
try {
Runnable o=queue.poll(10000, TimeUnit.MILLISECONDS);
if(o==null){
if(isUp==false){
return;
}
continue;
}
isFree.set(false);
o.run();
} catch (InterruptedException e1) {
e1.printStackTrace();
}// wait
}
}
CommandTracker
public void oneIsDone(WrappingCommandTask task) {
m_counter.decrementAndGet();
synchronized (this) {
if (m_counter.decrementAndGet() == 0) {
// signal
notify();
}
}
}
public boolean isAllDone() {
return m_counter.get() ==0;
}
To Be Continue...
目前还未对线程池里面每个线程的优先启用算法进行编写,而是采用了Queue的FIFO的模式
也就是说最先加入free队列的最先被启用。当线程池满的时候,任务会加入到线程是的waiting队列,此时优先级是LIFO,即最近需要加入free队列的线程最先被启用。
下一步需要考虑优先级可以为最少分配任务的那个线程做处理或者任务预分配。因为在WorkThread里面有个执行队列,因此在每个WorkThread里面设置一个阀值,允许一次加入的最大任务数。
分享到:
相关推荐
线程池(Thread Pool)是计算机程序设计中一种高效的线程管理机制,它允许程序员预先创建一组线程,而不是在需要时才动态创建。在"Pool_Thread.rar"这个压缩包中,包含了一个C语言实现的线程池示例,特别强调了其...
5. **线程池(Thread Pool)**:线程池可以有效管理线程资源,减少线程创建和销毁带来的开销,同时也便于实现线程间的同步。 6. **线程局部存储(Thread Local Storage, TLS)**:TLS是一种特殊的存储机制,它为每个...
本文将深入探讨C#中的线程和线程池,并结合"Multi-thread-pool-test.zip"中的示例,来阐述如何利用线程池实现多线程下载以及等高线处理。 **线程与线程池** 线程是操作系统分配CPU时间的基本单元,每个线程都有...
在ForkJoinPool中,线程被分为两类:工作线程(Worker Threads)和主控线程(Master Thread)。当一个任务被提交到ForkJoinPool时,它会被拆分成更小的子任务,然后这些子任务被放入双端队列(Deque)。每个工作线程...
`Linux_thread_pool.zip`中的`linux_threadpool.cpp`文件就是一个关于Linux线程池实现的示例,对于学习Linux下多线程编程具有很高的参考价值。 首先,让我们理解什么是线程池。线程池是由一组预先创建的线程组成的...
通过分析和学习这些示例,你可以更好地理解和应用Boost线程池。 总的来说,Boost线程池是C++中实现并发和并行计算的强大工具,它能够帮助开发者编写出高效、可扩展的多线程应用程序,尤其在处理大量并发任务时,其...
- 系统提供的线程池API,如`CreateThreadPool`和`SubmitThreadpoolWork`,可以有效管理线程生命周期,减少线程创建和销毁的开销。 6. **调试与性能分析**: - 使用`DebugPrint`或`OutputDebugString`进行线程调试...
【OKHttp多线程断点下载】是一种在Android或Java应用中实现高效文件下载的方法,它结合了OKHttp网络库...通过分析和理解这些代码,开发者可以学习如何在实际项目中实现OKHttp多线程断点下载功能,提升应用的下载体验。
10. **调试与分析**:使用Visual Studio的调试工具,如线程窗口,可以查看和控制多线程应用的执行情况,找出潜在问题。 理解并熟练掌握这些知识点,能帮助开发者构建稳定、高效的多线程Windows应用程序。在实际编程...
通过对这个测试程序的分析和学习,我们可以更好地理解线程池的运作方式,提高并发处理的效率,并为自己的项目选择合适的线程池实现策略。线程池的应用广泛,包括网络服务、数据库连接池、多任务调度等场景,熟练掌握...
4. `ConnectionPool.java`和`PoolManager.java`文件分析: - `ConnectionPool.java`很可能包含了创建和管理单个数据库连接的逻辑,比如使用Java的`java.sql.Connection`接口来创建数据库连接,以及实现连接的获取和...
Windows API提供了`CreateThreadPool`和`SubmitThreadpoolWork`等接口来管理线程池,线程池可以实现工作队列,按需分配线程处理任务。 这些实例源码将帮助开发者理解和实践以上五种线程同步技术,通过实际操作学习...
3. **线程执行器(Thread Pool)**:线程执行器,也称为线程池,是管理线程资源的一种机制。它预先创建一组线程,当有任务需要执行时,可以从池中获取线程而不是每次创建新的线程,这样可以减少线程创建和销毁的开销...
9. **案例分析**:书中可能会提供一些实际的多线程应用示例,帮助读者更好地理解理论知识,并应用于实际项目。 10. **最佳实践**:侯捷先生会分享他的编程经验和技巧,指导读者如何写出高效、稳定的多线程程序。 ...
5. **线程安全**:由于Apache Commons Pool 设计为多线程环境下的库,所有的操作都是线程安全的。这意味着你可以在并发环境中安全地使用它。 6. **异常处理**:当对象池中没有可用对象时,可以配置池抛出异常或者...
- **动态调整线程数**: `ForkJoinPool`会根据当前可用的处理器数量动态地调整线程的数量,以达到最优的资源利用。 - **工作窃取(Work Stealing)**: 这是一种任务调度策略,线程可以从其他线程的队列中窃取任务来...
同时,为了调试和分析,可能还需要使用条件变量(Condition Variable)和线程池(Thread Pool)等高级特性。 在"multithread"这个压缩包文件中,很可能包含了实现上述同步机制的源代码文件。通过分析这些代码,可以...
此外,它也可能包含监控和分析线程池性能的方法。 6. **线程局部存储(TLS)**:线程局部存储允许每个线程拥有自己的变量副本,而不会与其他线程共享。在处理并发任务时,这是一种避免数据冲突的有效手段。 7. **...
综上所述,通过学习和分析POCO C++库中的线程模块,尤其是ThreadPool类的设计和实现,可以了解到如何有效地管理多线程,实现异步处理、任务调度、资源管理和回收等高级特性。这些都是构建高效且可扩展的C++应用程序...
首先,我们需要分析Sphinx的构建流程,找出可以并行化操作的部分。通常,解析、渲染和输出是三个独立的步骤,这些步骤可以独立进行,非常适合多线程处理。 `construct_words.py`这个文件可能是用来构建词汇表或者...