【Java并发编程 线程池】27.线程池概念和Executor封装的四种线程池

线程池简介

创建若干个线程,放入池中,有任务需要处理了就提交到任务队列中,处理完不会销毁线程,而是仍然在任务队列中等待下个任务。

线程池优点

  1. 重复利用

  2. 提高响应速度(没有cpu时间调度)

  3. 管理线程

线程池的体系结构

java.util.concurrent.Executor : 负责线程的使用与调度的根接口                                        
    |--ExecutorService 子接口: 线程池的主要接口                                                
        |--ThreadPoolExecutor 线程池的实现类                                                 
        |--ScheduledExecutorService 子接口:负责线程的调度                                       
            |--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutor

Executor封装好了四种连接池类型

  • newCachedThreadPool:缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
  • newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。(工作中用的比较多)
  • newScheduledThreadPool:创建固定大小的线程,可以延迟或定时的执行任务。
  • newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

传统线程

for (int i = 0; i < 20; i++) {
    final int tmp = i;
    new Thread(new Runnable() {
        public void run() {
            System.out.println("传统创建线程"+Thread.currentThread().getName()+","+tmp);
        }
    }).start();
}

newCachedThreadPool

可缓存的线程 重复利用线程

//1.可缓存的线程 重复利用线程                                                
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();                
for (int i = 0; i < 20; i++) {                                                        
    final int tmp = i;                                                                
    newCachedThreadPool.execute(new Runnable() {                                      
        @Override                                                                     
        public void run() {                                                           
            System.out.println("threadName:"+Thread.currentThread().getName()+","+tmp);
        }                                                                             
    });                                                                               
}                                                                                                 

打印如下:

threadName:pool-1-thread-2,1
threadName:pool-1-thread-4,3
threadName:pool-1-thread-5,4
threadName:pool-1-thread-6,5
threadName:pool-1-thread-3,2
threadName:pool-1-thread-8,7
threadName:pool-1-thread-1,0
threadName:pool-1-thread-9,8
threadName:pool-1-thread-7,6
threadName:pool-1-thread-6,11
threadName:pool-1-thread-4,16
threadName:pool-1-thread-5,17
threadName:pool-1-thread-1,13
threadName:pool-1-thread-3,15
threadName:pool-1-thread-7,19
threadName:pool-1-thread-11,10
threadName:pool-1-thread-10,9
threadName:pool-1-thread-2,18
threadName:pool-1-thread-9,12
threadName:pool-1-thread-8,14

上图线程池只创建11个线程,相比传统线程,会创建20个线程,节省开销。

newFixedThreadPool

固定长度线程池

//2.固定长度线程池                                                                            
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);                  
for (int i = 0; i < 10; i++) {                                                         
    final int tmp = i;                                                                 
    newFixedThreadPool.execute(new Runnable() {                                        
        @Override                                                                      
        public void run() {                                                            
            System.out.println("threadName:"+Thread.currentThread().getName()+","+tmp);
        }                                                                              
    });                                                                                
}                                                                                      

打印如下:

threadName:pool-1-thread-3,2
threadName:pool-1-thread-5,4
threadName:pool-1-thread-4,3
threadName:pool-1-thread-2,1
threadName:pool-1-thread-1,0
threadName:pool-1-thread-2,8
threadName:pool-1-thread-4,7
threadName:pool-1-thread-3,5
threadName:pool-1-thread-5,6
threadName:pool-1-thread-1,9

newScheduledThreadPool

固定长度任务调度线程池

//3.固定长度任务调度线程池                                                                           
ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);    
for (int i = 0; i < 10; i++) {                                                            
    final int tmp = i;                                                                    
    newScheduledThreadPool.schedule(new Runnable() {                                      
        @Override                                                                         
        public void run() {                                                               
            System.out.println("threadName:"+Thread.currentThread().getName()+","+tmp);   
        }                                                                                 
    },3,TimeUnit.SECONDS);//3秒后同时执行                                                       
}                                                                                         

newSingleThreadExecutor

单线程

//4. 单线程
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();          
for (int i = 0; i < 10; i++) {                                                          
    final int tmp = i;                                                                  
    newSingleThreadExecutor.execute(new Runnable() {                                    
        @Override                                                                       
        public void run() {                                                             
            System.out.println("threadName:"+Thread.currentThread().getName()+","+tmp); 
        }                                                                               
    });                                                                                 
}                                                                                       

终止线程池

所有线程池在运行完后,后台都会在执行,需要调用shutdown方法,该方法调用后需要等待线程池中的线程执行完毕后再关闭进程。

ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();            
for (int i = 0; i < 10; i++) {                                                            
    final int tmp = i;                                                                    
    newSingleThreadExecutor.execute(new Runnable() {                                      
        @Override                                                                         
        public void run() {                                                               
            System.out.println("threadName:"+Thread.currentThread().getName()+","+tmp);   
        }                                                                                 
    });                                                                                   
}                                                                                         
//终止线程池                                                                                   
newSingleThreadExecutor.shutdown();                                                       

线程池和Callable的使用方式

线程池submit方法,在之前中一直使用execute方法,exeute存放Runnable类型的接口,submit方法存放Callable接口的线程,并且可以抛出异常和返回值。

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();                
Future<Integer> future = newCachedThreadPool.submit(new Callable<Integer>() {         
    public Integer call(){                                                            
        int sum = 0;                                                                  
        for (int i = 0;i<100;i++) {                                                   
            sum += i;                                                                 
        }                                                                             
        return sum;                                                                   
    }                                                                                 
});                                                                                   
newCachedThreadPool.shutdown();                                                       
System.out.println(future.get());                                                     
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

terrybg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值