스레드 풀



스레드 풀 (1)

스레드 풀과 여러 스레드의 세트에 넣어 같은 의미의 데이터베이스 연결 풀은 스레드 작업이 스레드의 완전한 파괴가 감소 다음 작업에 대한 스레드 풀 대기에,없는 경우, 태스크가 컬렉션에서 할당 창조와 파괴 스레드의 수는 창조와 파괴의 일환으로, 시스템 효율을 향상 重操作. 각각의 쓰레드를 생성하는 작업이있는 경우, 일자리 창출의 큰 유입은 너무 많은 스레드와 메모리 오버 플로우로 이어질 것




2. Excutor

java.util.concurrent.Executor에 인터페이스와 연관된 스레드 풀 및 구현 클래스의 일련되는 추출 부는 종래의 설명을 제공하는


UML 图 :


ExecutorService를 인터페이스 방법 :


AbstractExecutorService 클래스 방법 :

  • 실행] (Runnable를 명령)에있어서 정의 실행자 인터페이스
  • 관련 라이프 사이클 메소드 스레드의 ExecutorService를 정의
  • AbstractExecutorService는 기본 구현을 제공합니다
  • 스레드 풀 클래스의 사용을 권장 ThreadPoolExecutor입니다
  • ForkJoinPool 나중에 1.7 일부에서, 스레드 풀 클래스를 발견 논의되지





3. ThreadPoolExecutor입니다

이 클래스는 다른 스레드 풀을 만들 전달 다른 매개 변수에 따라, 스레드 풀을 생성하는 일반적인 방법을 제공, 생성자를 살펴

public ThreadPoolExecutor(
    
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler) {
    
    //省略具体逻辑,单看参数
}


  • corePoolSize를 : 스레드의 핵심 번호
    • 커널 스레드의 수보다 스레드 기존의 수는 요청을 처리하기 위해 새로운 스레드를 생성하는 경우
    • 스레드의 최대 수보다 커널 스레드의 수보다 기존 스레드의 수, 미만은 단지 전체 팀은 새 스레드를 생성하는 경우
    • 스레드 코어 수가 스레드의 최대 개수와 동일한 경우, 고정 된 크기의 스레드 풀을 만드는
    • 스레드의 최대 수는 무한하고있는 스레드 풀 크기 인 경우
  • maximumPoolSize를 : 스레드의 최대 수를
  • 이 KeepAliveTime : 유휴 대기 시간
    • 기존의 핵심 스레드의 수, 이후보다 스레드의 수는 유휴 시간이 남아있는 경우, 여분의 스레드가 파괴됩니다
  • 단위 : 단위 유휴 시간
  • 이 Workqueue : 큐잉 전략
    • 동기 전송 : 큐에 배치하지만, 대기 스레드를 실행할 수 없습니다. 현재의 thread가 수행되지 않으면 새 스레드를 열 가능성이 높습니다.
    • 제한 없음 전략 : 핵심 스레드가 작업하는 경우, 스레드는 큐에 배치되지 않습니다. 따라서, 더 이상 스레드 코어 스레드의 수보다
    • 有界限策略:可以避免资源耗尽,但是一定程度上减低了吞吐量
  • threadFactory:创建线程的工厂
  • handler:拒绝策略
    • 直接抛出异常
    • 使用调用者的线程来处理(多出的相当于没使用线程池)
    • 直接丢掉这个任务
    • 丢掉最老的任务




4. 线程池的状态

  • RUNNING:线程池能接受新任务,以及对新添加的任务进行处理
  • SHUTDOWN:线程池不接受新任务,但会对已添加的任务进行处理
  • STOP:线程池不接收新任务,不处理已添加的任务,并且会中断正在处理的任务
  • TIDYING:所有的任务已终止,ctl记录的"任务数量"为0,线程池会变为TIDYING状态,当线程池变为TIDYING状态时,会执行钩子函数terminated(),terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理,可以通过重载terminated()函数来实现
  • TERMINATED:线程池真正的终止




5. 线程池方法

execute(),submit(),shutdown(),shutdownNow() 是添加任务和关闭线程池的方法,前两者进行相应逻辑判断再考虑是否创建新线程,后两者是关闭线程池,区别于后者不等其任务完成就中断线程




6. 快捷创建线程池

在Executor类中,有下面几个静态方法来快捷创建线程池,下面写三个:

  • newFixedThreadPool:corePoolSize和maximumPoolSize相等
  • newCachedThreadPool:若新任务进来,没空闲进程会立马创建
  • SingleThreadExecutor:单线程,从队列中取任务执行




7. 线程任务


  • 获取线程的结果:
    • Future:Futrue模式就是Action先给Invoker一个未来(future),其实也就是票据,Invoker就可以继续接下来的步骤而无需等待Action结果的返回,通过 future.get() 可以获得返回值




  • 提交任务的种类:
    • Runnable:重写里面的run方法
    • Callable(可以认为是Runnable的扩展,多了返回值或异常):重写call方法
public static void main(String[] args) {
    
    //快捷线程池
    ExecutorService pool = Executors.newFixedThreadPool(10);
    
    //没有返回值
    Runnable runnable = () -> System.out.println("Runnable任务");
    
    //有返回值
    Callable callable = () -> {
        String msg = "Callable任务";
        System.out.println(msg);
        return msg;
    };
    
    //提交任务,并获取返回值
    Future f1 = pool.submit(runnable);
    Future f2 = pool.submit(callable);
    
    try {
        System.out.println("f1:" + f1.get());
        System.out.println("f2:" + f2.get());
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    
    //关闭线程池
    pool.shutdown();
}
Callable任务
Runnable任务
f1:null
f2:Callable任务




  • 提交任务的方式:
    • submit:可以接收Runnable,和Callable,有返回值和异常,底层还是用excute
    • execute ,只能接收Runnable,没有返回值

submit底层是用execute实现的:

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);     //把Callable变成RunnableFuture
    execute(ftask);         //把RunnableFuture传入execute
    return ftask;
}

Callable会被包装成RunnableFuture,在RunnableFuture的run中会调用callable的call方法,然后把返回值或异常放入该类的静态变量中




8.线程池实现

public static void main(String[] args) {
    
    //核心线程
    int corePoolSize = 5;
    //最大线程
    int maximumPoolSize = 10;
    //保持空闲时间
    long keepAliveTime = 10;
    //空闲时间单位,秒
    TimeUnit unit = TimeUnit.SECONDS;
    //排队策略,基于数组结构的有界阻塞队列
    BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(5);
    //设置创建线程的工厂,可以预设部分内容:eg:守护进程,优先级
    ThreadFactory threadFactory = Executors.defaultThreadFactory();
    //拒绝策略
    RejectedExecutionHandler handler = new AbortPolicy();;
    
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,
                                                                   maximumPoolSize,
                                                                   keepAliveTime,
                                                                   unit,
                                                                   workQueue,
                                                                   threadFactory,
                                                                   handler);
    
    Callable callable = () -> {
        String msg = "Callable任务";
        System.out.println(msg);
        return msg;
    };
    
    threadPoolExecutor.submit(() -> System.out.println("线程测试1"));
    threadPoolExecutor.submit(callable);

}
<!-- 打印 -->
线程测试1
Callable任务




추천

출처www.cnblogs.com/Howlet/p/12233870.html