首页 > 编程语言 >Java线程池

Java线程池

时间:2022-09-30 15:59:50浏览次数:54  
标签:Java 队列 创建 任务 线程 提交 执行

Java线程池

线程池的执行过程

  1. 当向线程池提交一个新的任务,线程池首先判断核心线程池的线程是否都在执行任务。如果不是,创建一个新的工作线程来执行任务。如果核心线程的线程都在执行任务,则进入下一个流程。

  2. 线程池判断工作队列是否已经满了,如果工作队列没有满,则将新提交的任务存储在这个工作队列里如果工作队列满了,则进入下一个流程

  3. 线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。

线程池创建的参数

public ThreadPoolExecutor(
 int corePoolSize,  
 int maximumPoolSize,
 long keepAliveTime,
 TimeUnit unit,
 BlockingQueue<Runnable> workQueue,
 ThreadFactory threadFactory,
 RejectedExecutionHandler handler
)
  1. corePoolSize(线程池的基本大小,核心线程池大小):提交一个新的任务到线程池,就会创建一个新的线程来执行任务,即使有空闲线程来执行任务,也会创建线程。直到待执行的任务数大于线程池基本大小就不再创建新的线程。如果调用了线程池的prestartCoreThread()方法,线程池会提前创建并启动所有的基本线程。

  2. workQueue(工作队列):用于在执行任务之前保存任务的队列。此队列用于保存向线程池提交的未处理的任务。

    1. ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序。
    2. LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量通常高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用这个队列。
    3. SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。
    4. DelayedWorkQueue:一个基于延迟时间排序的队列,Executors.newScheduledThreadPool()使用这个队列。
    5. LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列
    6. LinkedTransferQueue:一个由链表结构组成的无界阻塞队列
    7. PriorityBlockingQueue:一个具有优先级的无限阻塞队列
  3. maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务,如果使用了无界的任务队列这个参数就没有什么效果。

  4. ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字。

  5. RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。

    1. AbortPolicy(默认策略):直接抛出异常;

    2. CallerRunsPolicy:只用调用者所在线程来运行任务;

    3. DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务

    4. DiscardPolicy:不处理,丢弃掉

  6. keepAliveTime(线程活动保持时间): 线程池的工作线程空闲后,保持存活的时间。所以,如果任务很多,并且每个任务执行时间比较短,可以调大时间,提高线程利用率.

  7. unit:(线程活动保持时间的单位):可选的单位有天(DAYS)、小时(HOURS)、分钟(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和纳秒(NANOSECONDS,千分之一微秒)。

向线程池提交任务

  1. 使用execute() 方法提交。实现了Runable接口的线程
  ExecutorService threadPool = Executors.newFixedThreadPool(1);
   threadPool.execute(() -> {
   //TODO
   });
  1. 使用submit()方法提交。用于提交需要返回值的任务。线程池会返回一个future类型的对象
  <T> Future<T> submit(Callable<T> task);
  <T> Future<T> submit(Runnable task, T result);
  Future<?> submit(Runnable task
  ExecutorService threadPool = Executors.newFixedThreadPool(1);
  Future<String> future = threadPool.submit(() -> "Hello");
  try {
       String hello = future.get();
  } catch (InterruptedException e) {
       e.printStackTrace();
  } catch (ExecutionException e) {
       e.printStackTrace();
  }finally {
   // 关闭线程池
      threadPool.shutdown();
  }

注:本文参考于《Java并发编程艺术》第九章 Java中的线程池

标签:Java,队列,创建,任务,线程,提交,执行
From: https://www.cnblogs.com/pangcode/p/16737103.html

相关文章

  • 力扣500(java&python)-键盘行(简单)
    题目:给你一个字符串数组words,只返回可以使用在美式键盘同一行的字母打印出来的单词。键盘如下图所示。美式键盘中:第一行由字符"qwertyuiop"组成。第二行由字符"......
  • JAVA关键字修饰
    Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。default (即默认,什么也不写):在同一包内可见,不使用任何修饰符。使......
  • 避坑!SimpleDateFormat不光线程不安全,还有这个隐患
    众所周知,SimpleDateFormat是多线程不安全的下面这段代码通过多线程使用同一个SimpleDateFormat对象的parse方法,多次执行代码来测试,可以看到会出现两种预想不到的现象----......
  • java 遍历目录 删除目录 判断是否为目录
    删除目录privatestaticbooleandeleteDir(Filefile){if(file==null||!file.exists()){System.out.println("deletefilesfail,fi......
  • Java GUI编程(二)Swing
    一,窗口 二,弹窗publicclassDialogDemoextendsJFrame{publicDialogDemo(){this.setVisible(true);this.setSize(700,500);thi......
  • java mail实现POP3协议收件的Oauth认证
    1.背景   有team使用了office365的国际版邮箱进行收发邮件,但是微软会在十月一后关闭基本身份认证,选择使用OAuth身份验证连接IMAP、POP或SMTP协议,微软给出了相......
  • Java:通过标记直接跳出嵌套的循环结构
    这是我在刷面试题的时候遇到的一个使用方法,之前甚至对这种方法闻所未闻,不禁感慨自己的才疏学浅。闲话少说,直接进入正题。具体的使用就是在需要跳出的循环结构前面加一个......
  • java支持的运算符以及作用
    java语言支持如下运算符,优先级使用括号(),算数运算符:+,-,*,/,%(取余运算,或模运算),++(自增),--(自减)赋值运算符:=inta=10(把10赋值给a)关系运算符:>,<,>=,<=,==(java里等......
  • JavaScript大文件(百M以上)的上传下载实现技术
    ​最近遇见一个需要上传超大大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现。在某些业务中,大文件上传是一个比较重要的交......
  • 常用注解:Java、Spring框架
    Java8SpringFramework/Boot/Web-- Java中的注解【很神奇】。ben发布于博客园虽然用过很多,但是,对其感知仍然模糊,应该是对它们的使用原理不清楚所致。本文仅整理一......