多线程编程(五)--线程池

本文详细介绍了Java线程池的由来、优势及使用方法,包括固定线程池、缓存线程池和单一线程池的实现与运行效果分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDK 1.5之后加入了Java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用。为我们在开发中处理线程的问题提供了非常大的帮助。

 

一、池的由来

        拿数据库来举例子:每当一个请求到达就创建一个新的链接,但当有大量请求并发访问时,就会不断地创建和销毁链接,开销很大。为了提高效率,达到复用的效果,就有了池的概念。

        线程池是预先创建线程的一种技术。线程池在任务还没到来之前先创建一定数量的线程,放入空闲队列中。这些线程都是处于睡眠状态,即均为启动,不消耗CPU,而只是占用较小的内存空间。当请求到来之后,缓冲池给这次请求分配一个空闲线程,把请求传入此线程中运行,进行处理。当预先创建的线程都处于运行状态,即预制线程不够,线程池可以自由创建一定数量的新线程,用于处理更多的请求。当系统比较闲的时候,也可以通过移除一部分一直处于停用状态的线程。

 

二、使用线程池的好处

         1、减少了创建和销毁线程的次数,达到最大程度的复用对象

          2、线程代码和业务代码分离

 

三、线程池使用

         Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService

 

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、单一线程池

[java]  view plain copy print ?
  1. ExecutorService threadPool = Executors.newSingleThreadExecutor();  
  2. //池子里面只有一个线程,好处是如果池子里面的线程死掉,它会再启动一个线程所以实现了线程死后重启一个线程  


 

代码:

[java]  view plain copy print ?
  1. public static voidmain(String[] args) {  
  2. //固定的线程池  
  3. ExecutorService threadPool = Executors.newFixedThreadPool(3);  
  4.    
  5. //缓存的线程池  
  6. //                ExecutorServicethreadPool = Executors.newCachedThreadPool();  
  7.    
  8. //池子里面只有一个线程,好处是如果池子里面的线程死掉,它会再启动一个线程所以实现了线程死后重启一个线程  
  9. //                ExecutorServicethreadPool = Executors.newSingleThreadExecutor();  
  10.    
  11. for(int i = 1; i <= 10; i++) {  
  12. finalint task = i;  
  13. threadPool.execute(newRunnable() {  
  14. @Override  
  15. publicvoid run() {  
  16. for(int j = 1; j < 10; j++) {  
  17. try{  
  18. Thread.sleep(20);  
  19. }catch (InterruptedException e) {  
  20. //TODO Auto-generated catch block  
  21. e.printStackTrace();  
  22. }  
  23. System.out.println(Thread.currentThread().getName()  
  24. +" is looping of " + j + " for task of " + task);  
  25. }  
  26. }  
  27. });  
  28. }  
  29. System.out.println("allof 10 task have committed! ");  
  30. //6s以后炸,每隔2S炸一下  
  31. Executors.newScheduledThreadPool(3).scheduleAtFixedRate(newRunnable(){  
  32. @Override  
  33. publicvoid run() {  
  34. System.out.println("bombing");  
  35.    
  36.    
  37. }  
  38. }, 6,2, TimeUnit.SECONDS);  //6s以后炸,每隔2S炸一下  
  39. }  
  40.    
  41. }  

 

运行效果:

固定线程:

               

        当前设置了三个线程,故这三个线程在工作。FixedThreadPool中,有一个固定大小的池,如果当前需要执行的任务超过了池大小,那么多余的任务等待状态,直到有空闲下来的线程执行任务,而当执行的任务小于池大小,空闲的线程也不会去销毁。如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

 

缓存线程:

              

         这几个线程是交替工作的,CachedThreadPool会创建一个缓存区,将初始化的线程缓存起来,如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能添加新线程来处理任务。此线程池也不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。


单个线程池

              

       只有一个线程在工作。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值