热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

深入java线程池的使用详解

本篇文章是对java线程池的使用进行了详细的分析介绍,需要的朋友参考下
在Java 5.0之前启动一个任务是通过调用Thread类的start()方法来实现的,任务的提于交和执行是同时进行的,如果你想对任务的执行进行调度或是控制 同时执行的线程数量就需要额外编写代码来完成。5.0里提供了一个新的任务执行架构使你可以轻松地调度和控制任务的执行,并且可以建立一个类似数据库连接 池的线程池来执行任务。这个架构主要有三个接口和其相应的具体类组成。这三个接口是Executor, ExecutorService、ScheduledExecutorService,让我们先用一个图来显示它们的关系:

图的左侧是接口,图的右侧是这些接口的具体类。注意Executor是没有直接具体实现的。
Executor接口:是用来执行Runnable任务的,它只定义一个方法:
•execute(Runnable command):执行Ruannable类型的任务
ExecutorService接口:ExecutorService继承了Executor的方法,并提供了执行Callable任务和中止任务执行的服务,其定义的方法主要有:
•submit(task):可用来提交Callable或Runnable任务,并返回代表此任务的Future对象
•invokeAll(collection of tasks):批处理任务集合,并返回一个代表这些任务的Future对象集合
•shutdown():在完成已提交的任务后关闭服务,不再接受新任务
•shutdownNow():停止所有正在执行的任务并关闭服务。
•isTerminated():测试是否所有任务都执行完毕了。
•isShutdown():测试是否该ExecutorService已被关闭 
ScheduledExecutorService接口在ExecutorService的基础上,ScheduledExecutorService提供了按时间安排执行任务的功能,它提供的方法主要有:
•schedule(task, initDelay): 安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。
•scheduleAtFixedRate():安排所提交的Runnable任务按指定的间隔重复执行
•scheduleWithFixedDelay():安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。
 
重要的Executors类
虽然以上提到的接口有其实现的具体类,但为了方便Java 5.0建议使用Executors的工具类来得到Executor接口的具体对象,需要注意的是Executors是一个类,不是Executor的复数 形式。Executors提供了以下一些static的方法:
•callable(Runnable task):将Runnable的任务转化成Callable的任务
•newSingleThreadExecutor:产生一个ExecutorService对象,这个对象只有一个线程可用来执行任务,若任务多于一个,任务将按先后顺序执行。
•newCachedThreadPool():产生一个ExecutorService对象,这个对象带有一个线程池,线程池的大小会根据需要调整,线程执行完任务后返回线程池,供执行下一次任务使用。
•newFixedThreadPool(int poolSize):产生一个ExecutorService对象,这个对象带有一个大小为poolSize的线程池,若任务数量大于poolSize,任务会被放在一个queue里顺序执行。
•newSingleThreadScheduledExecutor:产生一个ScheduledExecutorService对象,这个对象的线程池大小为1,若任务多于一个,任务将按先后顺序执行。
•newScheduledThreadPool(int poolSize):产生一个ScheduledExecutorService对象,这个对象的线程池大小为poolSize,若任务数量大于poolSize,任务会在一个queue里等待执行

举例说明:
应用Executors来建立Thread pool
 
有时候您需要建立一堆Thread来执行一些小任务,然而频繁的建立Thread有时会是个开销,因为Thread的建立必须与作业系统互动,如果能建立一个Thread pool来管理这些小的Thread并加以重复使用,对于系统效能会是个改善的方式。
您可以使用Executors来建立Thread pool,Executors有几个static方法,列出如下:

方法 说明
newCachedThreadPool 建立可以快取的Thread,每个Thread预设可idle 60秒

newFixedThreadPool

包括固定数量的Thread

newSingleThreadExecutor

只有一个Thread,循序的执行指定给它的每个任务
newScheduledThreadPool 可排程的Thread
newSingleThreadScheduledExecutor 单一可排程的Thread

举个简单的实例,下面的程式使用newFixedThreadPool方法建立Thread pool,当中包括五个可以重复使用的Thread,您可以指定Runnable物件给它,程式中会产生十个Runnable物件,由于Thread pool中只有五个可用的Thread,所以后来建立的五个Runnable必须等待有空闲的Thread才会被执行:
•ExecutorDemo.java
代码如下:

package onlyfun.caterpillar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorDemo {
 public static void main(String[] args) {
  ExecutorService service = Executors.newFixedThreadPool(5);

  for(int i = 0; i <10; i++) {
   final int count = i;
   service.submit
(new Runnable() {
    public void run() {
     System.out.println(count);
     try {
      Thread.sleep(2000);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }

    }
   });
  }

  service.shutdown(); // 最后记得关闭Thread pool
 }
}

submit()方法也接受实作Callable介面的物件,最后传回Future物件,可以取得Callable执行过后的传回结果。如果想利用Executors进行排程,例如排定某个工作30秒后执行:
代码如下:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( );       
scheduler.schedule(new Runnable( ) {                              
public void run() {                                  
// 排程工作                              
}                          
},                          
30, TimeUnit.SECONDS);

或排定某个工作5秒后执行,之后每30秒执行一次:
代码如下:

 final ScheduledFuture future = scheduler.scheduleAtFixedRate(new Runnable( ) {                              
 public void run() {                                  
 // 排程工作                                  
 System.out.println("t");                              
 }                          
 },                          
 0, 5, TimeUnit.SECONDS);              
 // 排定 60 秒后取消future       
 scheduler.schedule(new Runnable( ) {           
 public void run( ) {             
 future.cancel(false);           
 }         
 }, 60, TimeUnit.SECONDS);

如上所示,想要取消排程任务,可以呼叫ScheduledFuture的cancel()方法。
推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • 本文介绍了使用SSH免密登录的步骤,包括生成公私钥、传递公钥给被登录机、修改文件权限的操作。同时提醒用户注意私钥的传递方式,建议使用U盘等离线方式传递。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • 原理:dismiss再弹出,把dialog设为全局对象。if(dialog!null&&dialog.isShowing()&&!(Activity.)isFinishing()) ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • 本文详细介绍了在Centos7上部署安装zabbix5.0的步骤和注意事项,包括准备工作、获取所需的yum源、关闭防火墙和SELINUX等。提供了一步一步的操作指南,帮助读者顺利完成安装过程。 ... [详细]
  • GSIOpenSSH PAM_USER 安全绕过漏洞
    漏洞名称:GSI-OpenSSHPAM_USER安全绕过漏洞CNNVD编号:CNNVD-201304-097发布时间:2013-04-09 ... [详细]
  • 本文介绍了在RHEL 7中的系统日志管理和网络管理。系统日志管理包括rsyslog和systemd-journal两种日志服务,分别介绍了它们的特点、配置文件和日志查询方式。网络管理主要介绍了使用nmcli命令查看和配置网络接口的方法,包括查看网卡信息、添加、修改和删除配置文件等操作。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
  •     这里使用自己编译的hadoop-2.7.0版本部署在windows上,记得几年前,部署hadoop需要借助于cygwin,还需要开启ssh服务,最近发现,原来不需要借助cy ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • Hadoop2.6.0 + 云centos +伪分布式只谈部署
    3.0.3玩不好,现将2.6.0tar.gz上传到usr,chmod-Rhadoop:hadophadoop-2.6.0,rm掉3.0.32.在etcp ... [详细]
author-avatar
mylvfamily
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有