美文网首页
为什么要使用线程池

为什么要使用线程池

作者: 笨笨翔 | 来源:发表于2019-03-19 12:20 被阅读0次

1.为什么要使用线程池

a.线程创建所需时间为T1,线程执行任务时间为T2,线程销毁时间为T3,而往往T1+T3>T2。所以频繁创建线程会损坏而外的时间。
b.如果有任务来了,再去创建线程的话效率比较低。
c.线程池可以管理控制线程,线程是稀缺资源,如果无休止的创建会消耗系统资源,还会降低系统稳定性。使用线程池可以进行统一分配,方便调优和监控。
d.线程池提供队列,存放缓冲等待执行任务。

ThreadPoolExecutor
参数

  1. corePoolSize:核心池大小
  2. maximumPoolSize:线程池最大线程数。
  3. keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有线程数大于核心线程corePoolSize时,该参数才会起作用。
  4. unit:参数keepAliveTime的时间单位
  5. workQueue:一个阻塞队列,用来存储等待执行的任务,有以下几种选择,ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue.
  6. threadFactory:线程工厂,主要用来创建线程。
  7. handler:便是当拒绝处理任务时的策略,四种取值:
    ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
    ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
    ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy:由点用线程处理该任务。

2.Java 线程池

Java通过Executors提供四种线程池,分别为:

  • newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool :创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool :创建一个定长线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor :创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
2.1 newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    for (int i = 0; i < 10; i++) {
        final int index = i;
    try {
        Thread.sleep(index * 1000);
    } 
        catch (InterruptedException e) {
            e.printStackTrace();
    }

cachedThreadPool.execute(new Runnable() {

@Override
public void run() {
    System.out.println(index);
}
});
}

线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

2.2 newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
    for (int i = 0; i < 10; i++) {
    final int index = i;

    fixedThreadPool.execute(new Runnable() {

@Override
public void run() {
try {
    System.out.println(index);
    Thread.sleep(2000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
}
});
}

因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。

定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。可参考PreloadDataCache。

2.3 newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
 scheduledThreadPool.schedule(new Runnable() {

@Override
public void run() {
    System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);

表示延迟3秒执行。

定期执行示例代码如下:

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

@Override
public void run() {
    System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);

表示延迟1秒后每3秒执行一次。

ScheduledExecutorService比Timer更安全,功能更强大

2.4 newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {

@Override
public void run() {
    try {
        System.out.println(index);
    Thread.sleep(2000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
        }
}
    });
}

结果依次输出,相当于顺序执行各个任务。

现行大多数GUI程序都是单线程的。Android中单线程可用于数据库操作,文件操作,应用批量安装,应用批量删除等不适合并发但可能IO阻塞性及影响UI线程响应的操作。

相关文章

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • 八、线程池剖析

    一、前置问题 线程的状态转换 为什么要使用线程池 线程池的继承体系 线程池使用的场景 线程数的设置规则 线程池的状...

  • 线程池概述

    为什么要使用线程池? 线程池核心参数 线程池的几种拒绝策略 execute()和submit()的区别 线程池工作...

  • Java线程池的原理及几类线程池的介绍

    在什么情况下使用线程池? 使用线程池的好处: 线程池工作原理:为什么要用线程池? 诸如 Web 服务器、数据库服务...

  • 线程池

    线程池 [TOC] 线程池概述 什么是线程池 为什么使用线程池 线程池的优势第一:降低资源消耗。通过重复利用已创建...

  • 线程池

    1.为什么要使用线程池?2.线程池的基本原理是什么?3.怎么学习线程池?线程池使用了池化技术。池化技术用于我们常见...

  • java线程池基础与原理

    为什么使用线程池 在没有线程池的场景,我们使用多线程时: 线程池的创建和销毁需要消耗额外的资源。线程的创建需要开辟...

  • 浅谈线程池

    前言1. 简介2. 为什么要使用线程池3. 线程池使用方式4. Executors创建线程池 3.1. newC...

  • 【多线程与并发】:线程池与Executor框架

    为什么要用线程池 关于为什么要使用多线程,请参考【多线程与并发】:线程的创建、状态、方法中的最后一点。 那为什么要...

  • 初识线程池

    线程池的重要性 复用每一个线程 控制线程的数量 为什么使用线程池 反复创建线程开销大,使用线程池可以重复利用已创建...

网友评论

      本文标题:为什么要使用线程池

      本文链接:https://www.haomeiwen.com/subject/hhdgmqtx.html