import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
BlockingQueue<Runnable> workQueue;
ThreadPoolExecutor pool;
public ThreadPoolTest() {
this.workQueue = new LinkedBlockingQueue<Runnable>();
this.pool = new ThreadPoolExecutor(5, 5, 600, TimeUnit.SECONDS, workQueue);
}
public static void main(String[] args) throws InterruptedException {
new ThreadPoolTest().process();
}
public void process() throws InterruptedException {
for(int i=0; i<100; i++) {
System.out.println("start putting task " + (i+1));
dispatchTask(i);
}
/**
* wait for all task to be completed
*/
while(workQueue.size()>1) {
System.out.println("there is still some task unfinish,sleep 5 seconds and check again");
Thread.sleep(5000);
}
System.out.println("finish all task");
pool.shutdown();
//if all task still not finish, sleep 5 seconds and check again
while(!pool.isTerminated()) {
pool.awaitTermination(5, TimeUnit.SECONDS);
}
}
public void dispatchTask(int index) throws InterruptedException {
/**
* most task in the waiting queue is 10
* if more than 10 then sleep 5 seconds
* and check the work queue size again
*/
while(workQueue.size() > 20) {
Thread.sleep(5000);
}
pool.submit(new MyTask(index));
}
}
class MyTask implements Runnable {
private int i;
public MyTask(int i) {
this.i = i;
}
public void run() {
System.out.println("Task " + (i+1) + " is processing!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
常用方法:
submit 提交一个Task去执行,并返回执行结果
awaitTermination 当执行线程中断、超时,或调用了shutdown方法后,阻塞直到所有的Task都执行结束。
shutdown 关闭所有执行过的Task,并不再接收新线程
isTerminated 如果所有Task都关闭则返回True,前提是调用过shutdown或shutdownNow
一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法欲添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue
handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
说明:
1、在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
2、一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
3、在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
这个小组里面队员至少有两个,如果他们两个忙不过来,任务就被放到任务列表里面。
如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
如果四个队员都在忙时,再有新的任务,这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发,直到接受这个任务为止(更残忍!呵呵)。
因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
4、通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制,改变这两个值就可以观察不同速率下程序的工作情况。
5、通过调整4中所指的数据,再加上调整任务丢弃策略,换上其他三种策略,就可以看出不同策略下的不同处理方式。
6、对于其他的使用方法,参看jdk的帮助,很容易理解和使用。
*/
分享到:
相关推荐
ThreadPool 线程池管理单元 带调用例子
"threadpool 线程池 C语言版"是针对C语言实现的一种线程池模型,其核心在于任务队列和线程组的管理,以实现线程的复用和优化。 线程池的工作原理是预先创建一定数量的线程,这些线程在池中待命,等待执行任务。当有...
Thread线程和ThreadPool线程池 Thread:我们可以开启一个线程。但是请大家记住:线程开启会在空间和时间上有不小的开销。所以,不能随便开。 ThreadPool:会根据你的CPU的核心数开启一个最合适的线程数量。如果你...
delphi版线程池调用,这个小项目网上实例很容易找到,对delphi初学者而言,仔细跟中调用步骤,更能理解实现。
C#多线程ThreadPool线程池详解 C#多线程ThreadPool线程池是C#中的一种线程管理机制,用于管理和维护线程池中的线程。下面是对C#多线程ThreadPool线程池的详细介绍。 一、线程池的定义 线程池可以看做容纳线程的...
DELPHI的线程池(ThreadPool)是一种高效管理并发任务的技术,它允许程序在需要时创建线程,而不是每次需要执行任务时都手动创建。线程池通过预先创建一组线程,然后根据需要分配任务,减少了线程创建和销毁的开销,...
自己实现的Python实现的线程池源码,测试通过
要理解`java线程池threadpool简单使用源码`,你需要查看`src`目录下的Java文件,了解如何实例化`ThreadPoolExecutor`,设置相关参数,以及如何提交任务到线程池。同时,查看源码中对`ThreadGroup`的使用,理解它如何...
通过`ThreadPool.QueueUserWorkItem`方法可以将工作项加入线程池,由线程池自动调度执行。 **线程同步**是多线程编程中的重要概念,用于控制不同线程对共享资源的访问。C#提供了多种同步机制,包括: 1. **Mutex**...
3. ThreadPool.SetMaxThreads / ThreadPool.SetMinThreads:设置线程池的最大和最小线程数,需谨慎使用,以免影响系统性能。 线程池的优势: 1. 资源优化:线程池避免了频繁创建和销毁线程的开销,节省了系统资源。...
基于C++11的threadpool线程池实现 在C++11标准中,加入了线程库,终于告别了标准库不支持并发的历史。然而,C++对多线程的支持仍然比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池、信号量等。 线程池...
在本示例"C#线程池使用demo"中,我们将探讨如何利用线程池来执行任务,以及其背后的原理和最佳实践。 首先,线程池主要由System.Threading命名空间下的ThreadPool类提供。在C#中,我们可以通过以下方式向线程池提交...
该软件包使用节点10.5的新辅助线程API实现线程池(请参阅: : )。 特征 轻量级:一个依赖项( surrial )进行序列化 简单的API:提交函数,等待结果(无需弄乱从文件,字符串等加载) 支持代码转换(例如:您可以...
线程池(ThreadPool)是一种管理线程资源的有效方式,它在现代并发编程中扮演着至关重要的角色。线程池允许程序预先创建一组线程,而不是每次需要时都创建新的线程,这样可以减少线程的创建和销毁开销,提高系统效率...
1. **ThreadPool.QueueUserWorkItem**:这是C#中使用线程池执行异步任务的主要方法。调用此方法时,传入一个委托(Delegate),线程池会在适当的时候执行该委托代表的方法。 2. **WaitHandle** 和 **...
在C#编程中,线程池(ThreadPool)是一种管理线程资源的有效机制,它能够高效地复用线程,减少创建和销毁线程的开销。线程池中的线程通常用于执行异步任务,因此在某些场景下,我们需要判断线程池中所有的线程是否...
在C#编程中,线程(Thread)和线程池(ThreadPool)是处理并发操作的重要概念,尤其是在开发Windows Forms(WinForm)应用程序时。本文将详细介绍C#中Thread和ThreadPool的基本用法及其应用场景。 ## 1. 线程...
线程池ThreadPool。
threadpool线程池学习