文档章节

Java并发编程高级篇(一):使用线程池执行器

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2017/02/28 14:50
字数 801
阅读 208
收藏 0

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

使用执行器框架(Executor Framework)的第一步是创建执行器ThreadPoolExecutor对象。我们可以使用ThreadPoolExecutor提供的四个构造函数,或者使用Executors工厂方法来创建线程执行器。一旦有了执行器,我们就可以把Runnable或Callable对象发送给它去执行了。

接下来我们使用执行器来实现一个能够处理客户端请求的服务器。

首先我们创建一个任务执行线程,这个线程用来模拟处理客户端的请求任务,它首先打印线程创建和启动时间,然后随机休眠一段时间用来模拟任务处理过程,最后打印任务结束时间。

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 任务执行类
 * Created by hadoop on 15/12/9.
 */
public class Task implements Runnable{
    private String name;
    private Date initDate;

    public Task(String name) {
        this.name = name;
        this.initDate = new Date();
    }

    /**
     * 任务过程
     * 1. 打印任务创建时间
     * 2. 打印任务开始时间
     * 3. 任务随机休眠一段时间
     * 4. 打印任务结束时间
     */
    @Override
    public void run() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.printf("%s: Task %s: Created on: %s\n",
                Thread.currentThread().getName(), name, format.format(initDate));
        System.out.printf("%s: Task %s: Started on: %s\n",
                Thread.currentThread().getName(), name, format.format(new Date()));

        long duration = (long)(Math.random() * 10);
        System.out.printf("%s: Task %s: Do something duration %d Seconds\n",
                Thread.currentThread().getName(), name, duration);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.printf("%s: Task %s: Finished on: %s\n",
                Thread.currentThread().getName(), name, format.format(new Date()));
    }
}

接下来我们创建服务端Server类,用来模拟接受客户端的请求,然后启动任务线程来处理请求,在这个类中,我们是用来线程处理器ThreadPoolExecutor。在这里我们使用了Executors.newCachedThreadPool()线程执行器工厂来创建线程执行器,这个方法会返回一个ExecutorService类型的对象,因此需要将它的类型转换为ThreadPoolExecutor类型。

如果需要执行任务,那么线程池执行器就会创建一个新的线程来执行这个任务,如果任务执行完毕,线程池会回收线程,当有新的任务进来的时候,将会从线程池中获取线程来执行这个任务。当然如果一次发送过多的任务给线程执行器,那么将会造成很高的系统负载。

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 任务调度类
 * 1. 启动一个线程池:(ThreadPoolExecutor) Executors.newCachedThreadPool();
 * 2. 接受任务并加入到线程池中
 * 3. 所有任务之行结束后关闭线程池
 * Created by hadoop on 15/12/9.
 */
public class Server {
    ThreadPoolExecutor executor;

    public Server() {
        executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
    }

    /**
     * 执行任务并打印当前线程池状态
     * @param task 任务
     */
    public void execute(Task task) {
        System.out.println("Server: A new task has arrived.\n");
        executor.execute(task);
        //返回线程池中的线程数
        System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize());
        //返回线程池中正在运行的线程数
        System.out.printf("Server: Active Count: %d\n", executor.getActiveCount());
        //返回线程池中已经完成的任务数
        System.out.printf("Server: Completed Task: %d\n", executor.getCompletedTaskCount());
    }

    public void endServer() {
        executor.shutdown();
    }
}

最后创建主类Main,并运行程序。

public class Main {
    /**
     * 创建10个任务并发送到线程池中
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Server server = new Server();
        for (int i = 0; i < 10; i++) {
            Task task = new Task("Task" + i);
            server.execute(task);
            Thread.sleep(1000);
        }
        server.endServer();
    }
}

© 著作权归作者所有

阿拉德大陆的魔法师
粉丝 27
博文 91
码字总数 83019
作品 0
西城
程序员
私信 提问
加载中

评论(0)

Java 并发编程-不懂原理多吃亏(送书福利)

作者 加多 关注阿里巴巴云原生公众号,后台回复关键字“并发”,即可参与送书抽奖!** 导读:并发编程与 Java 中其他知识点相比较而言学习门槛较高,从而导致很多人望而却步。但无论是职场面...

阿里巴巴云原生
2019/08/30
128
0
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
848
1
【原创】Java并发编程系列11 | 线程调度

  20大进阶架构专题每日送达       Java并发编程   本文为何适原创并发编程系列第 11 篇,前面几篇没看过的,可以在文末找到前几篇的跳转链接。本文介绍线程调度的如下几个操作:  ...

java进阶架构师
01/07
0
0
2020最全的并发编程篇:知识图鉴+知识点剖析+高频面试+书籍

知识图鉴(我真的尽力清晰了) 知识点剖析 1、JAVA 并发知识库 2、JAVA 线程实现/创建方式 3、4 种线程池 Java 里面线程池的顶级接口是 Executor,但是严格意义上讲 Executor 并不是一个线程...

飒拉阿依酱
04/24
0
0
2020之最专业的并发编程篇:知识图鉴+知识点剖析+高频面试+书籍

知识图鉴(我真的尽力清晰了) 知识点剖析 1、JAVA 并发知识库 2、JAVA 线程实现/创建方式 3、4 种线程池 Java 里面线程池的顶级接口是 Executor,但是严格意义上讲 Executor 并不是一个线程...

wx5d6cccb1cb158
04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

屏蔽nginx默认页面或者openresty默认页面

openresty是对nginx做了一层封装,屏蔽nginx或者openresty的默认页面的方法是一样的,就是对nginx/html/index.html进行修改即可。 ssh nginx@126.10.*.* // 使用ssh进行登录,根据提示输入密...

osc_2wznp7fr
1分钟前
0
0
基于Python的arcgis二次开发和ENVI二次开发

https://www.cnblogs.com/jhlong/p/5394530.html https://search.bilibili.com/all?keyword=arcgis%20python...

osc_gkcftr6g
1分钟前
0
0
[Go] gorm 返回指定模型数据的处理方式

重新 var 声明一个变量,类型为包含指定字段的结构体。 查询的时候,还是使用原始模型类型的变量。 example: // For return data var retMember struct { Hash string `json...

osc_eoffv2le
2分钟前
0
0
Spring boot Access-Control-Allow-Origin 问题解决

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import or......

osc_3361hjxk
3分钟前
0
0
通过人才测评系统,对程序员岗位进行招聘测评

一、 程序员的基本工作内容 1、 负责项目组内的代码维护和更新迭代,保证研发效率,对于运营产品提出的需求应积极沟通并实现。 2、 规范相关开发文档等相关资料,对于有变更的代码和功能需求...

蛤蟆丸子
4分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部