接着上篇说,好歹上面也加了个线程池,用好这概念,还是有些难度的,更不要说提出这些概念的人。可是看着看着发现技术又跟我前面记录的一样,是个熟悉的过程,我们逃脱不了技术工人,我不是个合格的,因为让我从无到有的写代码,我是一点都写不出来的,O(∩_∩)O~,不过技术在手里,用在哪里就看你了,要有希望,要有激情。今天扯远啦。
先从简单的并发的线程说起,一般实现线程都是实现Runnable接口或继承Thread类,后面又有了执行器(Executor)接口,其只有一个方法就是execute(Runnable command),其后有ExecutorService以及ScheduledExecutorService接口,对应的实现的类有ThreadPoolExecutor和ScheduledThreadExecutor,这样,Executor提供了一个简单的标准化接口,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。根据所使用的具体
Executor 类的不同,可能在新创建的线程中,现有的任务执行线程中,或者调用 execute() 的线程中执行任务,并且可能顺序或并发执行。可以从软件包 java.util.concurrent 的描述中看到这些实用的工具包对并发的支持。(下面简单的提一下,详细的应该查看标准文档)
(1)ExecutorService(接口):具有involveAll/invokeAny,shutdown,submit,完成批量或单独的任务提交,以及任务的终止等。
(2)ScheduledExecutorService(接口):可安排在给定的延迟运行或定期执行命令:schedule(),scheduleAtFixedRate(),scheduleWithFixDelay等。
再说回线程池,以ThreadPoolExecutor为例,也就是前面用到得。举例说明之前其实要说的是,如果没有特别的要求,最好使用Executors来创建需要的线程池,它会很好的处理线程池中线程的维护,任务的排队等等,如newCachedThreadPool() 创建一个可根据需要创建新线程的线程池,适合于短连接,处理轻任务的情况 ,newFixedThreadPool(int nThreads) 则是创建具有可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。如果真要自己来维护,那么就要考虑几个问题就是,线程池要维持多少个常在(预先开启的,即使没有在处理任务也依然存在的)线程,最大开启多少线程(也可以无限,直到资源耗尽),当现有线程比规定的常在线程数多时,它们该怎么处理;当有大量的任务请求到时,来不及处理的任务需要排队还是抛弃等等;我们可以先看看ThreadPoolExecutor的其中一个构造函数ThreadPoolExecutor(int
corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler),从中看到有到核心和最大池大小,保持活动时间,排队的三种通用策略,被拒绝的任务的处理等等,我就不细说了。下面看例子
package com.test.myjava;
import java.util.Queue;
import java.util.concurrent.*;
public class ThreadPoolTest {
private static int requestNum = 0;
public ThreadPoolExecutor threadPoolExecutor;
public static void main(String[] args) {
ThreadPoolTest tt = new ThreadPoolTest();
int corePoolSize = 2;
int maximumPoolSize = 5;
long keepAliveTime = 30;
int queueSize = 1;//5可以试一下
int queueNum = 0;
tt.threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,
keepAliveTime,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(queueSize),
new ThreadPoolExecutor.CallerRunsPolicy() );
//tt.threadPoolExecutor =(ThreadPoolExecutor) Executors.newFixedThreadPool(maximumPoolSize);
for(int i=0;i<5;i++ ){
System.out.println("Create Thread Num:"+i);
tt.threadPoolExecutor.execute(new RequestTasks(requestNum++));
queueNum = tt.getQueueSize(tt.threadPoolExecutor.getQueue());
if(queueNum!=0){
System.out.println("queueNum:"+queueNum);
}
}
}
private synchronized int getQueueSize(Queue queue) {
return queue.size();
}
}
// 处理请求的任务
class RequestTasks implements Runnable {
static int processedNum = 0;
int reqNum = 0;
RequestTasks(int reqNum){
this.reqNum = reqNum;
}
public void run() {
// TODO Auto-generated method stub
synchronized(this){//这里其实没用O(∩_∩)O~
processedNum++;
}
System.out.println("ProcessedNum:" + processedNum);
System.out.println("reqestNum"+reqNum);
//“ 去掉注释,看看只能响应两个,有些问题”这是上篇里说到的,
//自己也不懂原因,确实是不明白该怎样使用,现在清楚了
while (true)
;
}
}
如果直接运行的话,会发现当任务数达到corePoolSize规定的之后,新提交的任务就得不到执行,也是上篇说的新的请求得不到运行,可是任务队列也没有满,这是什么原因的:查看了实现的源码之后才知道,ThreadPoolExecutor的execute方法中(针对例子中使用的那个构造函数),当线程数达到corePoolSize时,新任务入队,但是只有当队伍满时或者旧有的线程运行完后才会处理队列中的任务。好了,说到这里。因此不是有特别要求还是用Executors来创建比较好。最后想说,有源码看还是很不错的,容易发现问题的所在。
分享到:
相关推荐
java线程池使用后到底要关闭吗 java线程池是一种高效的并发编程技术,可以帮助开发者更好地管理线程资源,提高系统的性能和可靠性。然而,在使用java线程池时,一个常见的问题是:使用完线程池后到底要不要关闭?...
java技术学习——基于Java线程池技术实现Knock Knock游戏项目(包含服务端、客户端两部分) java技术学习——基于Java线程池技术实现Knock Knock游戏项目(包含服务端、客户端两部分) java技术学习——基于Java...
在Java开发中,处理大批量数据时,合理利用线程池可以显著提高程序的执行效率和资源利用率。本文将深入探讨如何在Java中使用线程池来查询大量数据,以及这样做的好处和实现方法。 首先,理解线程池的概念至关重要。...
更多java相关内容感兴趣的读者可查看本站专题:《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》希望本文所...
Java全能学习面试手册——互联网企业面试真题.zip 01 java面试——北京-百度-Java中级.pdf 02 java面试——北京-京东-Java中级.pdf 03 java面试——广州-唯品会-Java大数据开发工程师.pdf 04 java面试——杭州-阿里...
简单的线程池程序+中文文档 包结构: com.tangkai.threadpool --SimpleThread.java 工作线程 --TestThreadPool.java 程序入口 --ThreadPoolManager.java 线程池管理类
环境:Windows XP ...这里本人翻写一个通用的线程池类,它可以用来作为工具类处理许多多线程问题。代码注释非常详尽,一行注释一行代码。 阅读对象:非常熟悉Java的基本概念,并且熟悉命令行编写代码的人员。
本文将深入探讨Java线程池的源码分析,并对比不同类型的线程池,以帮助开发者更好地理解和利用这一强大的工具。 首先,我们要理解Java线程池的核心类`java.util.concurrent.ThreadPoolExecutor`,它是所有自定义...
Java线程池是一种高效管理线程的技术,它可以帮助开发者更好地控制并发执行的线程数量,避免资源浪费,提高系统性能。在Java中,线程池是通过`java.util.concurrent`包中的`ExecutorService`接口及其实现类来实现的...
综上所述,本书《计算机算法——设计与分析导论》通过介绍算法的基本概念、分析算法的方式、使用数学背景来描述算法性能,以及提供具体的算法实例,为读者提供了一个全面了解计算机算法设计与分析的框架。...
利用Java进行疫情大数据分析——“Java面向对象程序设计”课程实践教学设计研究.pdf
- **RejectedExecutionHandler**:饱和策略,处理线程池饱和时的新任务。 3. **线程池的执行策略** - **AbortPolicy**:默认策略,抛出`RejectedExecutionException`异常。 - **CallerRunsPolicy**:调用者线程...
3. 使用@Async注解可以标记方法为异步执行,Spring会自动使用配置的线程池来执行该方法,从而提高系统并行处理能力。 三、数据同步控制问题 1. 在并发环境下,共享数据的访问可能导致数据不一致,需要采取同步机制...
标题解释: "java 在线查看PDF(csdn)————程序.pdf" 这个标题表明该代码的主要功能是在线查看 PDF 文件,并且这个示例代码来自 CSDN 平台。 描述解释: "java 在线查看PDF(csdn)————程序" 这个描述表明...
本文旨在使用Java语言编写一个通用的线程池。当需要使用线程池处理事务时,只需按照指定规范封装好事务处理对象,然后用已有的线程池对象去自动选择空 闲线程自动调用事务处理对象即可。并实现线程池的动态修改...
本Demo主要展示了如何在Java或Android环境中使用线程池,以下是对相关知识点的详细解释: 一、线程池概念 线程池是由多个工作线程组成的集合,它可以预先创建一定数量的线程,当有任务需要执行时,从池中取出一个...
通过深入研究和使用本资源提供的"JAVA经典线程池源码",开发者不仅可以理解线程池的基本工作原理,还能学习到如何自定义线程池以适应特定场景,从而提高程序的并发性能和稳定性。在实际项目中,结合Java并发API的...
java程序设计大作业——雷电飞机射击游戏(Java)java程序设计大作业——雷电飞机射击游戏(Java)java程序设计大作业——雷电飞机射击游戏(Java)java程序设计大作业——雷电飞机射击游戏(Java)java程序设计大...
在 Spring Boot 中使用 Java 线程池 ExecutorService 的讲解 Spring Boot 作为一个流行的 Java 框架,提供了许多便捷的功能来帮助开发者快速构建应用程序。其中之一就是使用 Java 线程池 ExecutorService 来管理...
Java线程池使用说明: 一 简介 二:线程池 三:ThreadPoolExecutor详解