当尝试用1000条数据并发向消息中心发送消息时,消息中心接收到消息打印了日志后,后面的日志就没有再打印出来了。100条也有这个问题,最后1条发现也是这样,于是发送一条消息断点测试:
//将消息中心介接收的数据wsData,交给线程池管理器InfoReceiveThreadPoolManager 处理
private void putReceiveCenter(WSData wsData ){
//将消息放入消息队列中
log.debug("加入消息接收队列开始:"+wsData.getMessage());
InfoReceiveThreadPoolManager poolManagert = InfoReceiveThreadPoolManager.getInstance();
poolManagert.addInfoQueue(wsData);
log.debug("加入消息接收队列结束:"+wsData.getMessage());
}
public class InfoReceiveThreadPoolManager{
private static final Logger log = Logger.getLogger(InfoReceiveThreadPoolManager.class);
private static InfoReceiveThreadPoolManager tpm = new InfoReceiveThreadPoolManager();
// 线程池维护线程的最少数量
private int CORE_POOL_SIZE = 50;
// 线程池维护线程的最大数量
private int MAX_POOL_SIZE = 100;
// 线程池维护线程所允许的空闲时间
private int KEEP_ALIVE_TIME = 0;
// 线程池所使用的缓冲队列大小
private int WORK_QUEUE_SIZE = 250;
// 消息缓冲队列
private Queue msgQueue = new LinkedList();
//获取管理器单例的消息并没有打印出来
public static InfoReceiveThreadPoolManager getInstance() {
log.debug("获取线程池管理器实例");
return tpm;
}
//如果线程池满了,消息队列也满了,则调用该handler处理
final RejectedExecutionHandler handler = new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
WSData data = ((ReceiveInfoTask) r).getWsData();
log.debug("消息接收中心拒绝处理,将消息再次加入消息队列中:"+data.getUuid());
boolean isAdded = false;
synchronized (msgQueue) {
isAdded = msgQueue.offer(data);
}
if(isAdded==false){
log.error("线程池满,无法添加消息:"+data.getUuid());
}
}
};
// 线程池
private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new ArrayBlockingQueue(WORK_QUEUE_SIZE), handler);
}
getInstance方法的debug日志没有打印出来,InfoReceiveThreadPoolManager实例化出错了。
debug发现时在下面new一个threadPool的时候,传入的WORK_QUEUE_SIZE 为0,quickServer报了一个ArrayBlockingQueue的IllegalArgumentException。
由于最初的threadPool被定义为了static的,所以它所用到的WORK_QUEUE_SIZE也是static的,后来threadPool被我修改为非静态的了。这里将WORK_QUEUE_SIZE也去掉static,执行getInstance方法可以正确获线程池的实例,如代码所示。
分享到:
相关推荐
5. **线程池初始化与销毁**:初始化线程池时,需要创建指定数量的线程并将它们设置为就绪状态。销毁线程池时,需确保所有任务都已完成,并安全地终止每个工作线程。 6. **任务调度**:线程池的核心功能是调度任务。...
1. **核心线程数**(Core Pool Size):线程池初始化时创建的线程数,即使无任务也需要保持这个数量的线程。这些线程始终存在,除非线程池被关闭。 2. **最大线程数**(Maximum Pool Size):线程池能容纳的最大...
1. **线程池初始化**:在程序启动时,开发者需要调用`CreateThreadpool`函数创建一个线程池。这会初始化线程池结构体,准备接受任务。 2. **任务调度**:当需要执行新任务时,可以使用`SubmitThreadpoolWork`函数...
1. **线程池初始化**:通过调用`CreateThreadpool`来创建线程池对象,设置线程池的属性,如最小和最大线程数量。 2. **任务提交**:使用`QueueUserWorkItem`将任务加入线程池的工作队列。每个任务通常是一个函数...
1. **线程创建与初始化**:线程池初始化时,会创建一定数量的线程并准备好待用。这些线程通常在创建时就设置为后台线程,以避免阻塞进程的退出。线程可能需要设置相应的属性,如优先级、栈大小等。 2. **任务队列**...
1. **线程池初始化**:线程池的创建通常涉及到初始化线程数量、任务队列等参数。`ThreadPool`类可能会有一个构造函数,接受线程数量作为参数。 2. **任务提交机制**:线程池需要有一个方法接收任务并安排执行。这...
1. **线程池初始化**:首先,我们需要创建一个线程池结构体,用于存储线程池的相关信息,如线程数组、工作队列、线程数量等。初始化时,我们会根据需求设置线程池的大小,并创建相应数量的线程。 2. **工作队列**:...
2. **线程池初始化**:在`ThreadPool.cpp`中,提供一个初始化函数,用于创建指定数量的工作线程,并启动它们。这些工作线程会等待任务的分配。 3. **任务提交接口**:设计一个接口,允许用户向线程池提交任务。提交...
在Linux中,可以使用pthread库来创建和管理线程,线程池的实现通常包括线程池初始化、任务提交、线程调度和线程销毁等步骤。 接着,目录拷贝的核心在于遍历目录结构。在Linux中,可以使用`opendir()`函数打开一个...
- **线程池初始化**:设置线程池大小,创建线程并保存在数据结构中。 - **任务队列**:存放待处理的任务,通常使用队列数据结构。 - **调度策略**:决定何时分配任务给线程,如轮询、优先级等。 - **线程同步**...
2. **核心线程(Core Threads)**:线程池初始化时创建的线程数量,当有任务提交到线程池时,如果核心线程未满,会立即创建新的线程执行任务。 3. **最大线程(Maximum Threads)**:线程池能容纳的最大线程数。...
1. **线程池初始化**:初始化时,线程池需要创建一定数量的线程并保持就绪状态。这些线程可以在需要时立即处理任务,而无需等待新线程的创建。 2. **任务队列**:任务队列用于存储待执行的任务。线程池中的线程从...
1. **线程池初始化**:创建线程池时,需要确定线程的数量,这通常取决于系统的资源和任务的性质。初始化过程包括创建预定义数量的线程并设置其初始状态。 2. **任务队列**:线程池维护一个任务队列,用来存储待处理...
1、线程池初始化时,会起多个独立线程作为线程池的work进程; 2、可修改线程池的work线程数量,需要简单修改下接口即可; 3、可设置线程的cpu亲和性绑核,就是cpu在线程调度时,会让该线程优先调度到亲和性高的cpu...
通常情况下,这种类型的线程池用于我们确切知道应用程序可用资源的数量的情况,这样固定数目的线程就可以在线程池初始化过程中创建完成。面这种情况正好适用于这种类型:我们为企业内部网开发解决方案或者在可以严格...
线程池初始化时需要设定线程数量,可以根据系统资源和任务性质进行调整。 3. **任务提交**:任务的提交一般通过函数接口实现,该接口将任务包装为结构体,并放入工作队列。任务可能包含一个函数指针,以及任何必要...
1. 核心线程数:线程池初始化时创建的线程数,即使无任务也会保持这些线程。 2. 最大线程数:线程池允许的最大线程数,超过此数的任务会被放入工作队列。 3. 工作队列:存储等待执行任务的队列,有无界和有界两种...
- **核心线程数**:线程池初始化时创建的线程数,这些线程会一直存活,即使它们暂时没有任务可做。 - **最大线程数**:线程池允许的最大线程数,当提交的任务数量超过核心线程数时,新创建的线程不会超过这个值。 ...
- **线程池初始化**:创建指定数量的线程,将它们设置为等待状态。 - **任务提交**:使用`std::function`或函数指针封装任务,然后加入任务队列。 - **线程执行**:工作线程从队列中获取任务,执行后返回队列等待...