自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. 无法定位程序输入点 Can't load package

    ---------------------------Toggle Form/Unit (F12): bcb.exe - 无法找到入口--------------------------- 无法定位程 ...

  2. Spring Boot实践——多线程

    多线程 Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程.使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor.而实际开发中任务一 ...

  3. Beetlsql自定义生成entity,mapper,md代码

    三个模板文件 mapper.btl package ${package}; import org.beetl.sql.core.annotatoin.*; import org.beetl.sql.c ...

  4. Tomcat域名映射和端口设置

    1.打开tomcat主目录  --->  打开conf目录 ---> 找到并打开server.xml文件 2.修改tomcat的监听端口为80端口 在文件中找到: <Connecto ...

  5. 查看linux中某个端口(port)是否被占用

    1.使用lsof lsof -i:端口号                     查看某个端口是否被占用 2.使用netstat 使用netstat -anp|grep 80

  6. 784. Letter Case Permutation 字符串中字母的大小写组合

    [抄题]: Given a string S, we can transform every letter individually to be lowercase or uppercase to c ...

  7. IPMI设置与使用(远程控制服务器)

    如果服务器crash了或者就hang住了,我们不必要跑到机房去按电源键的,因为我们也想“运筹帷幄之中,决胜千里之外”嘛.我们可以用IPMI,它可以让我们远程用一条命令开启(关闭.重启)一台服务器,也可 ...

  8. c语言字符串指针

    最近正在看c语言,在指针这块遇到了麻烦,特别是字符串指针这块,简单记录下. 字符串指针 void main() { char *p = "tasklist"; printf(&qu ...

  9. Spring JMX之一:使用JMX管理Spring Bean

    spring中关于jmx包括几个概念: MBeanExporter: 从字面上很容易理解, 用来将一些spring的bean作为MBean暴露给MBEanServer.MBeanServerFacto ...

  10. MySQL redo log及recover过程浅析

    写在前面:作者水平有限,欢迎不吝赐教,一切以最新源码为准. InnoDB redo log 首先介绍下Innodb redo log是什么,为什么需要记录redo log,以及redo log的作用都 ...