zoukankan      html  css  js  c++  java
  • 线程池

    线程池

    一、前言

      Java中创建线程共有四种方法,前三种前面已经做过详细介绍,不清楚的朋友可以看看我的这几篇博文:

      Java多线程之线程的启动

      Java多线程之Thread与Runnable

      通过Callable接口创建线程

      这里介绍第四种创建线程的方法:线程池(可以类比于数据库连接池)

      线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。

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

    二、Java线程池体系结构

      如上图所示,Java线程池的体系结构分析如下

      图中的三个接口是线程池的核心接口

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

      Executor根接口下的ExecutorService子接口,它使用可能的几个池线程之一执行每个提交的任务,通常使用Executors 工厂方法配置。

      每个ThreadPoolExecutor 维护着一些基本的统计数据,如完成的任务数。

    三、工具类 : Executors

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

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

      ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。(无界线程池,可以进行自动线程回收)

      ExecutorService newSingleThreadExecutor() : 创建单个线程池。线程池中只有一个线程(单个后台线程)

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

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

    四、示例代码

     1 package me.concurrent.tp;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 import java.util.concurrent.Callable;
     6 import java.util.concurrent.ExecutorService;
     7 import java.util.concurrent.Executors;
     8 import java.util.concurrent.Future;
     9 
    10 /**
    11  * 通过newFixedThreadPool线程池创建线程
    12  */
    13 public class TestThreadPool {
    14 
    15     public static void main(String[] args) throws Exception {
    16     // 1. 创建线程池
    17     ExecutorService pool = Executors.newFixedThreadPool(5);
    18 
    19     List<Future<Integer>> list = new ArrayList<>();
    20 
    21     for (int i = 0; i < 10; i++) {
    22         Future<Integer> future = pool.submit(new Callable<Integer>() {
    23 
    24         @Override
    25         public Integer call() throws Exception {
    26             int sum = 0;
    27 
    28             for (int i = 0; i <= 100; i++) {
    29             sum += i;
    30             }
    31 
    32             return sum;
    33         }
    34 
    35         });
    36 
    37         list.add(future);
    38     }
    39 
    40     pool.shutdown();
    41 
    42     for (Future<Integer> future : list) {
    43         System.out.println(future.get());
    44     }
    45 
    46     /*
    47      * ThreadPoolDemo tpd = new ThreadPoolDemo();
    48      * 
    49      * //2. 为线程池中的线程分配任务 
    50      * for (int i = 0; i < 10; i++) { 
    51      *     pool.submit(tpd); 
    52      * }
    53      * 
    54      * //3. 关闭线程池 
    55      * pool.shutdown();
    56      */
    57     }
    58 
    59     // new Thread(tpd).start();
    60     // new Thread(tpd).start();
    61 
    62 }
    63 
    64 class ThreadPoolDemo implements Runnable {
    65 
    66     private int i = 0;
    67 
    68     @Override
    69     public void run() {
    70     while (i <= 100) {
    71         System.out.println(Thread.currentThread().getName() + " : " + i++);
    72     }
    73     }
    74 }
    View Code

    如果,您对我的这篇博文有什么疑问,欢迎评论区留言,大家互相讨论学习。
    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
    如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
    如果,您对我的博文感兴趣,可以关注我的后续博客,我是【AlbertRui】。

    转载请注明出处和链接地址,欢迎转载,谢谢!

  • 相关阅读:
    WCF 第四章 绑定 在多个绑定上暴露一个服务契约
    WCF 第五章 行为 事务跨操作事务流
    WCF 第五章 导出并发布元数据(服务行为)
    WCF 第五章 行为 通过配置文件暴露一个服务行为
    WCF 第五章 不支持会话的绑定的默认并发和实例
    WCF 第五章 并发和实例(服务行为)
    WCF 第五章 行为 总结
    WCF 第四章 绑定 绑定元素
    WCF 第五章 行为 事务之选择一个事务协议OleTx 或者WSAT
    WCF 第四章 绑定 比较各种绑定的性能和可扩展性
  • 原文地址:https://www.cnblogs.com/albertrui/p/8406528.html
Copyright © 2011-2022 走看看