• 线程池


    线程池

    一、前言

      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】。

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

  • 相关阅读:
    小程序用户拒绝授权地理位置的处理办法
    云开发小程序数据库权限有限,通过云函数修改数据库评论信息
    小程序仿照微信朋友圈点击评论键盘输入
    小程序wx.previewImage查看图片再次点击返回时重新加载页面问题
    js手机端判断滑动还是点击
    Proxy
    Reflect.has检测对象是否拥有某个属性
    简单的axios请求返回数据解构赋值
    为windows terminal 配置 conda
    git clone 遇到问题:fatal: unable to access 'https://github.comxxxxxxxxxxx':
  • 原文地址:https://www.cnblogs.com/albertrui/p/8406528.html
Copyright © 2020-2023  润新知