多线程——newCachedThreadPool线程池

newCachedThreadPool线程池:

理解:

  1).newCachedThreadPool可以创建一个无限大小的线程池(实际上是一个可缓存线程池)。

  可以通过Executors的静态方法创建线程池:

    public static ExecutorService newCachedThreadPool() 或者

     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) 。

  2).返回的是ExecutorService对象线程池。

  3).newCachedThreadPool在执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它是合理的Executor的首选。

   只有当这种方式会引发问题时(内存溢出),你才需要切换到newFixedThreadPool()。

  4).无限制不代表不可以复用线程,假设说一开始进来10个任务,启动了10个线程,10个任务结束后,然后又来了5个任务(线程还没被回收),

  这时候会复用之前的线程,不会新起线程,这就达到了使用“线程池”的意义。

使用场景:
  1. 耗时较短的任务。
  2. 任务处理速度 > 任务提交速度 ,这样才能保证不会不断创建新的进程,避免内存被占满。

//首先看Executors中通过newCachedThreadPool创建线程池的方法的源码
//此方法是通过new一个ThreadPoolExecutor来创建的
//这个构造方法有5个参数:
//第一个参数corePoolSize(核心池大小)为0,
//第二个参数maximumPoolSize(最大线程池大小)为Integer.MAX_VALUE无限大,源码中是:public static final int   MAX_VALUE = 0x7fffffff;
//第三个参数keepAliveTime(线程存货的时间)是60秒,意味着线程空闲时间超过60秒就会被杀死。
//第五个参数采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,
//    如果当前没有空闲的线程,那么就会再创建一条新的线程。
public class Executors {
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
}

//ThreadPoolExecutor类中此构造函数源码:
public class ThreadPoolExecutor extends AbstractExecutorService {
      public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
    }
}

下面是Thinking in java书中的例子:

public class LiftOff implements Runnable {
    protected int countDown = 5;
    private static int taskCount = 0;
    private final int id = taskCount++;

    public LiftOff() {
    }

    public LiftOff(int countDown) {
        this.countDown = countDown;
    }

    public String status() {
        return "# " + id + " ( " + (countDown > 0 ? countDown : "LiftOff !") + " )";
    }

    @Override
    public void run() {
        while (countDown-- > 0) {
            System.out.println(status());
            Thread.yield();
        }
    }
}
public class CachedThreadPool {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executorService.execute(new LiftOff());
        }
    }
}
结果:
# 2 ( 4 )
# 0 ( 4 )
# 1 ( 4 )
# 2 ( 3 )
# 0 ( 3 )
# 2 ( 2 )
# 1 ( 3 )
# 2 ( 1 )
# 0 ( 2 )
# 2 ( LiftOff ! )
# 1 ( 2 )
# 0 ( 1 )
# 1 ( 1 )
# 0 ( LiftOff ! )
# 1 ( LiftOff ! )

原文地址:https://www.cnblogs.com/whx20100101/p/9862382.html

时间: 2024-11-05 15:58:50

多线程——newCachedThreadPool线程池的相关文章

多线程及线程池学习心得

一.线程的应用与特点 多线程是程序员不可或缺的技术能力,多线程技术在各个方面都有应用,特别在性能优化上更是起到至关重要的作用.但是,如果多线程写得不好,往往会适得其反,特别是高并发时会造成阻塞.超时等现象.多线程具有以下特点:1.独立性,拥有自己独立的资源,拥有自己私有的地址空间:2.动态性,进程具有自己的生命周期和各种不同的状态:3.并发性,多个进程可以在单个处理器上并发执行,不会相互影响,并行是指同一时刻有多条指令在多个处理器上同时执行.线程是进程的组成部分,一个进程可以拥有多个线程,一个线

java多线程之线程池

自JDK5之后,Java推出了一个并发包,java.util.concurrent,在Java开发中,我们接触到了好多池的技术,String类的对象池.Integer的共享池.连接数据库的连接池.Struts1.3的对象池等等,池的最终目的都是节约资源,以更小的开销做更多的事情,从而提高性能. 我们的web项目都是部署在服务器上,浏览器端的每一个request就是一个线程,那么服务器需要并发的处理多个请求,就需要线程池技术,下面来看一下Java并发包下如何创建线程池. 1.  创建一个可重用固定

C#多线程之线程池篇3

在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关知识. 五.使用等待句柄和超时 在这一小节中,我们将学习如何在线程池中实现超时和正确地实现等待.具体操作步骤如下: 1.使用Visual Studio 2015创建一个新的控制台应用程序. 2.双击打开"Program.cs"文件,编写代码如下所示: 1 using System; 2 u

C#多线程之线程池篇2

在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我们将学习对于大量的异步操作,使用线程池和分别使用单独的线程在性能上有什么差异性.具体操作步骤如下: 1.使用Visual Studio 2015创建一个新的控制台应用程序. 2.双击打开"Program.cs"文件,编写代码如下所示: 1 using System; 2 using Sys

java多线程、线程池的实现

Java实现多线程的3种方法:继承Thread类.实现runnable接口.使用ExecutorService,Callable.Future实现有返回值的多线程.前2种线程的实现方式没有返回值,第三种实现方式可以获取线程执行的返回值. 一:继承java.lang.Thread类 public class MyThread extends Thread { @Override public void run() { System.out.println( "my thread begin.&qu

多线程和线程池

有这样一个需求:你有一个list集合,需要使用该集合作为参数,调用另一个系统并返回结果后处理它(主要的目的是处理结果) 解决方案:用线程池,不关闭线程池,将多个线程放入一个List集合中,使用invokeAll方法,相当于是将多个线程打包执行,统一返回,这样线程池可以一直不关闭,不用为了一个list开一个线程池,并且多个线程打包调用不会造成和其他用户的多线程冲突(究竟是你的线程还是我的线程). ExecutorService cachedThreadPool = Executors.newCac

java 多线程和线程池

● 多线程 多线程的概念很好理解就是多条线程同时存在,但要用好多线程确不容易,涉及到多线程间通信,多线程共用一个资源等诸多问题. 使用多线程的优缺点: 优点: 1)适当的提高程序的执行效率(多个线程同时执行). 2)适当的提高了资源利用率(CPU.内存等). 缺点: 1)占用一定的内存空间. 2)线程越多CPU的调度开销越大. 3)程序的复杂度会上升. 对于多线程的示例代码感兴趣的可以自己写Demo啦,去运行体会,下面我主要列出一些多线程的技术点. synchronized 同步块大家都比较熟悉

进程与线程的区别?--多线程与线程池

每个进程都是一个程序,进程之间相互独立.除分布式外,进程数据之间,内存是不共享的. 线程存在于进程之中,一个进程包括一个或多个线程,每个线程都是一条路径,线程之间共享数据. 多线程 优点:合理利用CPU资源,单线程独占CPU资源,浪费CPU资源.并且可以提高程序的运行效率 缺点:1.如果有大量的线程运行,会消耗大部分内存,会影响性能(可能会死机),CPU需要他们之间的切换. 2.线程运行可能会出现死锁.线程安全问题(修改操作时你要考虑使用synchronized.lock(接口).volatil

多线程--Executor线程池框架

Executor的介绍 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动.执行和关闭,可以简化并发编程的操作.因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逃逸问题——如果我们在构造器中启动一个线程,因为另一个任务可能会在构造器结束之前开始