Java-Executor框架浅析

Java线程池:

Java线程池在Java并发中应用十分广泛。使用线程池也会带来很多好处:1.降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁的消耗;2.提高响应速度。当任务到达时,任务可以不需要等待线程创建就可以立即执行;3.提高线程的可管理性。使用线程池可以对线程进行统一分配、调优和监控。

线程池原理:在线程池得到初始化之后,提交新任务到线程池。1.线程池判断线程是否已全部被使用。否,就调用一个的工作线程处理新加任务。如果线程池没有空余线程,就将任务加入队列。2.线程池判断工作队列是否已满。如果工作队列未满,将任务加入工作队列等候处理。如果工作队列也满了,根据线程池配置选择是否保留任务。3.线程池判断其中的已经在工作的线程数量是否超出了最大数量。如果没有就创建一个线程执行任务。如果满了就交给饱和策略进行处理

线程池的实现:以下是用伪代码实现的一个线程池的模板。

public class MyThreadPool{
    public MyThreadPool(){
        initWorkThread(DEFAULT_NUMBER);
    }
    public MyThreadPool(int number){
        initWorkThread(number);
    }

    public void execute(Job job){
        if(job != null){
            synchornized(jobs){
                jobs.addLast(job);
                jobs.notify(); //加入工作队列,并通知有新任务
            }
        }
    }
    
    public void addWorkers(int num){
        //增加工作线程
    }

    public void removeWorker(){
        //删除工作线程
    }
    public void initWorkThread(int num){
         for(int i = 0;i < num;i++){
            Worker worker = new Worker();
            workes.add(worker);
         }
    }
}


Java并发框架Executor框架:

在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当Java线程终止时,这个操作系统线程也会被回收。可以将此中模式分为两层,在上层中Java通过并发框架创建一定数量的线程;在底层,操作系统将创建的操作系统线程映射到CPU上进行处理。

Executor框架结构:主要分为三大部分:1.任务。包括执行任务需要实现的接口Runnable和Callable。2.任务的执行。包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)。3.异步计算的结果。包括接口Future和实现接口Future的FutureTask类。

Executor框架的主要类介绍:ThreadPoolExecutor是线程池的核心实现类,主要由4个组件构成:corePool:核心线程池大小。maximumPool:最大线程池的大小。BlockingQueue:用来暂时保存任务的工作队列。RejectedExecutionHandler:当线程池关闭或已达到饱和时execute()方法将调用的Handler。由此也可以看出实现一个线程池就是基于这几个重要的组件。

ThreadPoolExecutor可以创建3中类型的线程池:

(1)FixedThreadPool,该类的特点就是可以重用固定数量线程的线程池。

执行过程如下:

1.如果当前工作中的线程数量少于corePool的数量,就创建新的线程来执行任务。

2.当线程池的工作中的线程数量达到了corePool,则将任务加入LinkedBlockingQueue。

3.线程执行完1中的任务后会从队列中去任务。

注意LinkedBlockingQueue是无界队列,所以可以一直添加新任务到线程池。

(2)SingleThreadExecutor,该类的特点是使用单个工作线程执行任务。

执行过程如下:

1.如果当前工作中的线程数量少于corePool的数量,就创建一个新的线程来执行任务。

2.当线程池的工作中的线程数量达到了corePool,则将任务加入LinkedBlockingQueue。

3.线程执行完1中的任务后会从队列中去任务。

注意:由于在线程池中只有一个工作线程,所以任务可以按照添加顺序执行。

(3)CacheThreadPool,该类的特点是可以根据需要来创建新的线程执行任务,没有特定的corePool。

执行过程如下:

1.首先执行SynchronousQueue.offer(Runnable task)。如果在当前的线程池中有空闲的线程正在执行SynchronousQueue.poll(),那么主线程执行的offer操作与空闲线程执行的poll操作配对成功,主线程把任务交给空闲线程执行。

2.当线程池为空或没有空闲线程时,配对失败,线程池就会创建一个新的线程来执行任务。

3.在创建完新的线程以后,将会执行poll操作。

SynchronousQueue是一个不存储元素阻塞队列,每次要进行offer操作时必须等待poll操作,否则不能继续添加元素。

### 1. 在 IntelliJ IDEA 中编译项目 #### 编译 timer - job - admin 为 WAR 包 在 IntelliJ IDEA 中打开 `timer - job - admin` 项目,确保项目的 `pom.xml` 中打包方式为 `war`。在 IDEA 的右侧 Maven 工具窗口中,依次点击 `Lifecycle` 下的 `clean` 和 `package`,编译完成后,会在项目的 `target` 目录下生成 `timer - job - admin.war` 包。 #### 编译 timer - job - shell - executor 和 timer - job - java - executor 为 JAR 包 同样在 IntelliJ IDEA 中打开 `timer - job - shell - executor` 和 `timer - job - java - executor` 项目,确保 `pom.xml` 中打包方式为 `jar`。在 Maven 工具窗口中,对这两个项目分别执行 `Lifecycle` 下的 `clean` 和 `package` 操作,编译完成后,在各自项目的 `target` 目录下会生成对应的 JAR 包。 ### 2. 部署 timer - job - admin 到 Linux Tomcat #### 上传 WAR 包 使用 `scp` 命令将 `timer - job - admin.war` 包上传到 Linux 服务器上的 Tomcat 的 `webapps` 目录下。例如: ```bash scp /本地路径/timer - job - admin.war root@服务器IP:/tomcat/webapps/ ``` #### 启动 Tomcat 进入 Tomcat 的 `bin` 目录,执行以下命令启动 Tomcat: ```bash cd /tomcat/bin ./startup.sh ``` Tomcat 启动后会自动解压 `timer - job - admin.war` 包。 ### 3. 以 JAR 包方式启动 timer - job - shell - executor 和 timer - job - java - executor #### 上传 JAR 包 使用 `scp` 命令将 `timer - job - shell - executor.jar` 和 `timer - job - java - executor.jar` 上传到 Linux 服务器的指定目录。例如: ```bash scp /本地路径/timer - job - shell - executor.jar root@服务器IP:/指定目录/ scp /本地路径/timer - job - java - executor.jar root@服务器IP:/指定目录/ ``` #### 启动 JAR 包 在 Linux 服务器上,进入存放 JAR 包的目录,分别执行以下命令启动两个 JAR 包: ```bash cd /指定目录/ nohup java -jar timer - job - shell - executor.jar & nohup java -jar timer - job - java - executor.jar & ``` ### 4. 在任务调度中心新建并成功执行调度任务 #### 访问任务调度中心 在浏览器中输入 `http://服务器IP:Tomcat端口/timer - job - admin` 访问 XXL - JOB 任务调度中心,使用默认的用户名和密码登录。 #### 新建执行器 在任务调度中心的菜单中找到 `执行器管理`,点击 `新增`,填写执行器的相关信息,如 `AppName`、`名称` 等,点击 `保存`。 #### 新建任务 在 `任务管理` 中点击 `新增`,填写任务的基本信息,包括 `执行器`、`任务描述`、`调度类型`、`调度表达式` 等。在 `任务参数` 中可以填写执行任务所需的参数。选择 `GLUE 类型` 为适合的类型,编写任务的执行代码,点击 `保存`。 #### 执行任务 在 `任务管理` 列表中找到新建的任务,点击 `启动` 按钮,任务会按照设定的调度规则执行。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值