12JUC--线程池&线程调度

Posted mrchengs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12JUC--线程池&线程调度相关的知识,希望对你有一定的参考价值。

线程池

? 第四种获取线程的方法:线程池,一个 ExecutorService,它使用可能的几个池线程之
  一执行每个提交的任务,通常使用 Executors 工厂方法配置。


? 线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在
  执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行
  任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数
  据,如完成的任务数。


? 为了便于跨大量上下文使用,此类提供了很多可调整的参数和扩展钩子 (hook)。但
  是,强烈建议程序员使用较为方便的 Executors 工厂方法 :


? Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)


? Executors.newFixedThreadPool(int)(固定大小线程池)


? Executors.newSingleThreadExecutor()(单个后台线程)

  它们均为大多数使用场景预定义了设置

 

 

线程池:

提供了一个线程队列,队列中保存着等待状态的线程

避免了创建和销毁,提高了响应速度

技术图片

技术图片

 

线程池的体系结构

java.util.concurrent.Excutor:负责线程的使用与调度的根接口

  --ExecutorService子接口:线程池的主要接口

    --ThreadPoolExecutor:线程池的实现类

    --ScheduleExecutorService:子接口:负责线程的调度

      --ScheduleThreadPoolExecutor:继承了ThreadPoolExecutor实现类ScheduleExecutorService接口

 

工具类:Executors

ExecutorService newFixedThreadPool():创建固定大小的线程池

ExecutorService  newCacheThreadPool():缓存线程池,线程池的数量不固定,可以根据需求修改数量

ExecutorService newSingleThreadEcecutor():创建单个的线程池,线程池中只有一个线程

 

ScheduleExecutorService newScheduledThreadPool():创建固定大小的线程,可以延迟或定时的执行任务

 

1、实现Runnable接口

class ThreadDemos implements Runnable{
    private int i =0;
    @Override
    public void run() {
        while(i <20){
            System.out.println( Thread.currentThread().getName() + ":" + i++);
        
        }
    }
}

 

public static void main(String[] args) {
        //1创建一个线程池,5个线程
        ExecutorService pool = Executors.newFixedThreadPool(5);
        
        ThreadDemos td = new ThreadDemos();
        //2、为线程池中的线程分配任务
        //pool.submit(td);
        for(int  i = 0; i <10;i++){
            pool.submit(td);
        }  
        
        //3、关闭线程池
        pool.shutdown();
        
    }

结果:

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

此时的线程池中最多就创建了5个线程

 

2、Callable

public class TestThreadPool {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //1创建一个线程池,5个线程
        ExecutorService pool = Executors.newFixedThreadPool(5);
        
        List<Future<Integer>> list = new ArrayList<>();
        
        for(int i = 0;i<10;i++){
            //使用匿名内部类进行创建
            Future<Integer> f =     pool.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int sum = 0;
                    for(int i = 0 ;i < 20;i++){
                        sum +=i;
                    }
                    return sum;
                }
            });
            
            list.add(f);
        }

        //关闭
        pool.shutdown();
        
        for(Future<Integer>  future:list){
            System.out.println(future.get());
        }
        
    }
}

遍历结果:

技术图片

 

 

线程调度

ScheduleExecutorService newScheduledThreadPool():创建固定大小的线程,可以延迟或定时的执行任务

ScheduledExecutorService

一个 ExecutorService,可安排在给定的延迟后运行或定期执行的命令

代码展示

public class TestScheduledThreadPool {
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        
        //1、创建线程池
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
        
        //2、
        for(int i=0;i<=20;i++){
            //    public ScheduledFuture<?> schedule(Runnable command,
            //        long delay, TimeUnit unit);
            //参数1:为线程池分配任务
            //参数2:延时
            //参数3:延时的类型
            Future<Integer> f =  pool.schedule(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int number = new Random().nextInt(100);
                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    return number;
                }
            }, 3, TimeUnit.SECONDS);
            System.out.println(f.get());
        }                                  
        /关闭
        pool.shutdown();
        
    }

}

此时是3s进行一个打印输出

技术图片

 

以上是关于12JUC--线程池&线程调度的主要内容,如果未能解决你的问题,请参考以下文章

JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 任务调度线程池 定时任务 / 延时执行(ScheduledThreadPoolExecutor 延时执行 / 定时执行)(代

JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 任务调度线程池 定时任务 / 延时执行(Timer的缺点)

JUC系列线程池基础使用

Java多线程系列--“JUC线程池”02之 线程池原理

Java多线程系列--“JUC线程池”02之 线程池原理

Java - "JUC线程池" ThreadPoolExecutor原理解析