首页 > 编程语言 >Java线程篇(六):线程池

Java线程篇(六):线程池

时间:2022-12-14 15:35:14浏览次数:45  
标签:Java 任务 线程 print java 执行 view


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

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

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



[java]  view plain copy print ?





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


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



[java]  view plain copy print ?





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


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



[java]  view plain copy print ?





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




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



[java]  view plain copy print ?





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


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

        1. FixedThreadPool



[java]  view plain copy print ?





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


        输出结果:



[java]  view plain copy print ?





  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方法。

        输出结果:



[java]  view plain copy print ?





  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方法。       

       输出结果:



[java]  view plain copy print ?





  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    



[java]  view plain copy print ?





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


         ScheduledThreadPool可以定时的或延时的执行任务。

标签:Java,任务,线程,print,java,执行,view
From: https://blog.51cto.com/u_15912341/5937202

相关文章

  • eclipse运行java.lang.OutOfMemoryError: PermGen space解决方法
    一、在window下eclipse里面Server挂的是tomcat6,一开始还是以为,tomcat配置的问题,后面发现,配置了tomcat里面的catalina.bat文件,加入 setJAVA_OPTS=-Xms512m-Xmx1024m-XX......
  • javaweb之文件上传总结
    一。文件上传:是指允许客户将本地文件,上传到服务器端 常见的应用:上传照片、上传新闻图片、上传附件 文件上传编程基本步骤: 1、在用户页面中添加上传输入项(客户端页......
  • 读书笔记-阿里巴巴Java开发手册-常用的命名风格
    命名风格强制类型不可以用​​_​​​或者​​$​​开始或者结束严禁使用拼音和英文混写类名使用UpperCamelCase风格方法名,参数名,成员变量,局部变量都统一使用lowerCamelCase......
  • LeetCode-Java-872. Leaf-Similar Trees
    题目Consideralltheleavesofabinarytree.Fromlefttorightorder,thevaluesofthoseleavesformaleafvaluesequence.假装有图Forexample,inthegiven......
  • 剑指Offer-Java-二叉树的镜像
    题目题目描述操作给定的二叉树,将其变换为源二叉树的镜像。输入描述:二叉树的镜像定义:源二叉树8/\610/\/\57911......
  • 16-咸鱼学Java-内部类补充
    上一篇文章,说了实例内部类和静态内部类,这篇文章重点说明,本地内部类和方法内部类本地内部类也叫本地方法内部类,局部内部类。指在一个方法内定义的类,只有在当前方法中才能对局......
  • LeetCode-Java-136. Single Number
    题目Givenanon-emptyarrayofintegers,everyelementappearstwiceexceptforone.Findthatsingleone.Note:Youralgorithmshouldhavealinearruntimecompl......
  • LeetCode-Java-637. Average of Levels in Binary Tree
    题目Givenanon-emptybinarytree,returntheaveragevalueofthenodesoneachlevelintheformofanarray.Example1:Input:3/\920/\15......
  • Java泛型链表实现
    ​​链表简介​​代码实现packagecom.chenxixuexi;/***泛型链表*单链表逆置数据--节点*求单链表倒数第K节点*求两个单链表是否相交相交交点*判断单链表是否有......
  • 15-咸鱼学Java-内部类
    实例内部类实例内部类简而言之就是类里面嵌入着类,就像环套环一样Demo:classOuterClass2//外部类{privateinta=1000;publicOuterClass2(){Sy......