文档章节

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

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2017/02/28 14:50
字数 801
阅读 60
收藏 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();
    }
}

© 著作权归作者所有

共有 人打赏支持
阿拉德大陆的魔法师
粉丝 24
博文 91
码字总数 83019
作品 0
西城
程序员
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

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

Hi徐敏
2015/11/11
0
1
JAVA多线程和并发基础面试问答

原文链接 译文连接 作者:Pankaj 译者:郑旭东 校对:方腾飞 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢...

雷神雨石
2014/07/19
0
2
JAVA多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:...

LCZ777
2014/05/26
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

清风傲剑
2014/12/06
0
0
读书笔记之《Java并发编程的艺术》-并发编程基础

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

Hi徐敏
2015/11/11
0
8

没有更多内容

加载失败,请刷新页面

加载更多

深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
46分钟前
2
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
56分钟前
2
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
9
0
JavaEE——Junit

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 Junit Junit又名单元测试,Junit是用来测试Jav...

凯哥学堂
昨天
6
0
读《美丽新世界》

一、背景 十一国庆节从重庆回深圳的时候,做得绿皮车,路上看了两本书:李笑来的《韭菜的自我修养》和禁书《美丽新世界》。 上篇文章已经分享了 读《韭菜的自我修养》,这篇文章来记录一下《...

tiankonguse
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部