自JDK5之后,Java推出了一个并发包,java.util.concurrent,在Java开发中,我们接触到了好多池的技术,String类的对象池、Integer的共享池、连接数据库的连接池、Struts1.3的对象池等等,池的最终目的都是节约资源,以更小的开销做更多的事情,从而提高性能。

我们的web项目都是部署在服务器上,浏览器端的每一个request就是一个线程,那么服务器需要并发的处理多个请求,就需要线程池技术,下面来看一下Java并发包下如何创建线程池。

1.  创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程。

  1. ExecutorService threadPool = Executors.newFixedThreadPool(3);// 创建可以容纳3个线程的线程池

2. 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

  1. ExecutorService threadPool = Executors.newCachedThreadPool();// 线程池的大小会根据执行的任务数动态分配

3. 创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。

  1. ExecutorService threadPool = Executors.newSingleThreadExecutor();// 创建单个线程的线程池,如果当前线程在执行任务时突然中断,则会创建一个新的线程替代它继续执行任务

4. 创建一个可安排在给定延迟后运行命令或者定期地执行的线程池。

  1. ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);// 效果类似于Timer定时器

每种线程池都有不同的使用场景,下面看一下这四种线程池使用起来有什么不同。

1. FixedThreadPool

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. public class ThreadPoolTest {
  4. public static void main(String[] args) {
  5. ExecutorService threadPool = Executors.newFixedThreadPool(3);
  6. for(int i = 1; i < 5; i++) {
  7. final int taskID = i;
  8. threadPool.execute(new Runnable() {
  9. public void run() {
  10. for(int i = 1; i < 5; i++) {
  11. try {
  12. Thread.sleep(20);// 为了测试出效果,让每次任务执行都需要一定时间
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. System.out.println("第" + taskID + "次任务的第" + i + "次执行");
  17. }
  18. }
  19. });
  20. }
  21. threadPool.shutdown();// 任务执行完毕,关闭线程池
  22. }
  23. }

输出结果:

  1. 第1次任务的第1次执行
  2. 第2次任务的第1次执行
  3. 第3次任务的第1次执行
  4. 第2次任务的第2次执行
  5. 第3次任务的第2次执行
  6. 第1次任务的第2次执行
  7. 第3次任务的第3次执行
  8. 第1次任务的第3次执行
  9. 第2次任务的第3次执行
  10. 第3次任务的第4次执行
  11. 第2次任务的第4次执行
  12. 第1次任务的第4次执行
  13. 第4次任务的第1次执行
  14. 第4次任务的第2次执行
  15. 第4次任务的第3次执行
  16. 第4次任务的第4次执行

上段代码中,创建了一个固定大小的线程池,容量为3,然后循环执行了4个任务,由输出结果可以看到,前3个任务首先执行完,然后空闲下来的线程去执行第4个任务,在FixedThreadPool中,有一个固定大小的池,如果当前需要执行的任务超过了池大小,那么多于的任务等待状态,直到有空闲下来的线程执行任务,而当执行的任务小于池大小,空闲的线程也不会去销毁。
        2. CachedThreadPool

上段代码其它地方不变,将newFixedThreadPool方法换成newCachedThreadPool方法。

输出结果:

  1. 第3次任务的第1次执行
  2. 第4次任务的第1次执行
  3. 第1次任务的第1次执行
  4. 第2次任务的第1次执行
  5. 第4次任务的第2次执行
  6. 第3次任务的第2次执行
  7. 第2次任务的第2次执行
  8. 第1次任务的第2次执行
  9. 第2次任务的第3次执行
  10. 第3次任务的第3次执行
  11. 第1次任务的第3次执行
  12. 第4次任务的第3次执行
  13. 第2次任务的第4次执行
  14. 第4次任务的第4次执行
  15. 第3次任务的第4次执行
  16. 第1次任务的第4次执行

可见,4个任务是交替执行的,CachedThreadPool会创建一个缓存区,将初始化的线程缓存起来,如果线程有可用的,就使用之前创建好的线程,如果没有可用的,就新创建线程,终止并且从缓存中移除已有60秒未被使用的线程。

3. SingleThreadExecutor

上段代码其它地方不变,将newFixedThreadPool方法换成newSingleThreadExecutor方法。

输出结果:

  1. 第1次任务的第1次执行
  2. 第1次任务的第2次执行
  3. 第1次任务的第3次执行
  4. 第1次任务的第4次执行
  5. 第2次任务的第1次执行
  6. 第2次任务的第2次执行
  7. 第2次任务的第3次执行
  8. 第2次任务的第4次执行
  9. 第3次任务的第1次执行
  10. 第3次任务的第2次执行
  11. 第3次任务的第3次执行
  12. 第3次任务的第4次执行
  13. 第4次任务的第1次执行
  14. 第4次任务的第2次执行
  15. 第4次任务的第3次执行
  16. 第4次任务的第4次执行

4个任务是顺序执行的,SingleThreadExecutor得到的是一个单个的线程,这个线程会保证你的任务执行完成,如果当前线程意外终止,会创建一个新线程继续执行任务,这和我们直接创建线程不同,也和newFixedThreadPool(1)不同。

4.ScheduledThreadPool

  1. import java.util.concurrent.ScheduledExecutorService;
  2. import java.util.concurrent.TimeUnit;
  3. public class ThreadPoolTest {
  4. public static void main(String[] args) {
  5. ScheduledExecutorService schedulePool = Executors.newScheduledThreadPool(1);
  6. // 5秒后执行任务
  7. schedulePool.schedule(new Runnable() {
  8. public void run() {
  9. System.out.println("爆炸");
  10. }
  11. }, 5, TimeUnit.SECONDS);
  12. // 5秒后执行任务,以后每2秒执行一次
  13. schedulePool.scheduleAtFixedRate(new Runnable() {
  14. @Override
  15. public void run() {
  16. System.out.println("爆炸");
  17. }
  18. }, 5, 2, TimeUnit.SECONDS);
  19. }
  20. }

ScheduledThreadPool是一个固定大小的线程池,与FixedThreadPool类似,执行的任务是定时执行。

Java的并发包很强大,上面所说只是入门,随着学习深入,会有更多记录在博客里。

本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7443324,转载请注明。

java线程池(一)的更多相关文章

  1. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

  2. Java线程池使用说明

    Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...

  3. (转载)JAVA线程池管理

    平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...

  4. Java线程池的那些事

    熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...

  5. 四种Java线程池用法解析

    本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...

  6. Java线程池的几种实现 及 常见问题讲解

    工作中,经常会涉及到线程.比如有些任务,经常会交与线程去异步执行.抑或服务端程序为每个请求单独建立一个线程处理任务.线程之外的,比如我们用的数据库连接.这些创建销毁或者打开关闭的操作,非常影响系统性能 ...

  7. Java线程池应用

    Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThread ...

  8. Java线程池的原理及几类线程池的介绍

    刚刚研究了一下线程池,如果有不足之处,请大家不吝赐教,大家共同学习.共同交流. 在什么情况下使用线程池? 单个任务处理的时间比较短 将需处理的任务的数量大 使用线程池的好处: 减少在创建和销毁线程上所 ...

  9. Java线程池与java.util.concurrent

    Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行 ...

  10. [转 ]-- Java线程池使用说明

    Java线程池使用说明 原文地址:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1. ...

随机推荐

  1. AngularJS学习笔记(1)——MVC模式的清单列表效果

    MVC模式的清单列表效果 使用WebStorm新建todo.html并链入bootstrap.css.bootstrap-theme.css.angular.js.要链入的相关css和js文件预先准备 ...

  2. oracle创建新数据库

    oracle创建新数据库 look here http://www.cnblogs.com/phoenixzq/p/3510854.html windows start menu>Oracle& ...

  3. StrConv 内码转换

    StrConv(string,conversion,LCID) string,预转换的字符串了(也可以使用byte数组). Conversion: 是一个整数,只决定转换方式,VB里定义了一些常量,如 ...

  4. protobuf's custom-options

    [protobuf's custom-options] protobuf可以设置属性,就像__attribute__可以给函数设置属性一样,protobuf更牛的是可以设置自定义属性.实际就是属性对象 ...

  5. Pollard Rho因子分解算法

    有一类问题,要求我们将一个正整数x,分解为两个非平凡因子(平凡因子为1与x)的乘积x=ab. 显然我们需要先检测x是否为素数(如果是素数将无解),可以使用Miller-Rabin算法来进行测试. Po ...

  6. Spring IOC容器启动流程源码解析(一)——容器概念详解及源码初探

    目录 1. 前言 1.1 IOC容器到底是什么 1.2 BeanFactory和ApplicationContext的联系以及区别 1.3 解读IOC容器启动流程的意义 1.4 如何有效的阅读源码 2 ...

  7. 2015年传智播客JavaEE 第168期就业班视频教程11-导入配置文件

    资源文件放在Source Folder目录下面,这个目录同样会编译到classes目录下 web.xml的 <listener> <listener-class>org.spr ...

  8. 分区恢复和NTFS文件恢复试验

    一.实验室名称:主楼实验室A2-412                  二.实验项目名称:分区恢复和NTFS文件恢复试验 三.实验学时:6学时 四.实验原理: 借助fdisk.diskgen软件对磁 ...

  9. Oracle ADF VO排序及VO的查询模式

    常规应用中,当需要使用Table向终端用户展示数据时,Table中数据的显示排序一致性极大程度的影响到了客户体验.通常希望诸如多次查询结果显示顺序相同.插入数据在原数据上方等的实现. ADF为开发人员 ...

  10. Putty建立隧道的方法[z]

    通过上节我们了解了SSH隧道的优点,但是无论是现实中还是网络中,隧道都是有入口和出口的,本节就以Putty隧道为例,详细介绍Putty建立隧道的方法. 模拟案例一: 端口,出口为2012端口,隧道建立 ...