线程学习四:线程池

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

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

一、newCachedThreadPool

 1 public class NewCachedThreadPool {
 2     public static void main(String[] args) throws InterruptedException {
 3         ExecutorService es = Executors.newCachedThreadPool();
 4         RunnableTest1 rt = new RunnableTest1();
 5         es.execute(rt);
 6         Thread.sleep(2000);
 7         System.out.println("sleep finish");
 8         es.execute(rt);
 9     }
10 }
11
12 class RunnableTest1 implements Runnable {
13     public void run() {
14         for (int i = 0; i < 100; i++) {
15             System.out.println(Thread.currentThread().getName() + "...." + i);
16         }
17     }
18 }

如果上一个任务已经使用线程完毕,下一个任务会调用之前的线程,不会再创建;如果任务没有完毕,会创建新线程。

二、newFixedThreadPool

 1 public class NewFixedThreadPool {
 2     public static void main(String[] args) throws InterruptedException {
 3         ExecutorService es = Executors.newFixedThreadPool(2);
 4         RunnableTest rt = new RunnableTest();
 5         es.execute(rt);
 6         Thread.sleep(2000);
 7         System.out.println("sleep finish");
 8         es.execute(rt);
 9     }
10 }
11
12 class RunnableTest implements Runnable {
13     public void run() {
14         for (int i = 0; i < 100; i++) {
15             System.out.println(Thread.currentThread().getName() + "...." + i);
16         }
17     }
18 }

规定线程池里面最大线程数,定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。

三、newScheduledThreadPool

 1 public class NewScheduledThreadPool {
 2     public static void main(String[] args) {
 3         ScheduledExecutorService es = Executors.newScheduledThreadPool(2);
 4         RunnableTest2 rt = new RunnableTest2();
 5         es.scheduleAtFixedRate(rt, 0, 3, TimeUnit.SECONDS);
 6         es.execute(rt);
 7     }
 8 }
 9
10 class RunnableTest2 implements Runnable {
11     public void run() {
12         for (int i = 0; i < 100; i++) {
13             System.out.println(Thread.currentThread().getName() + "...." + i);
14         }
15     }
16 }

可以设置线程的延迟时间以及隔多久执行一次,注意这里是调用ScheduledExecutorService的scheduleAtFixedRate()方法,与其他线程池不同。

四、newSingleThreadScheduledExecutor

 1 public class NewSingleThreadExecutor {
 2     public static void main(String[] args) {
 3         ExecutorService es = Executors.newSingleThreadScheduledExecutor();
 4         RunnableTest3 rt = new RunnableTest3();
 5         es.execute(rt);
 6         es.execute(rt);
 7     }
 8 }
 9
10 class RunnableTest3 implements Runnable {
11     public void run() {
12         for (int i = 0; i < 100; i++) {
13             System.out.println(Thread.currentThread().getName() + "...." + i);
14         }
15     }
16 }

会将并行的线程按一定排序串行执行。

五、线程池关闭

我们可以通过调用线程池的shutdown或shutdownNow方法来关闭线程池,它们的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。但是它们存在一定的区别,shutdownNow首先将线程池的状态设置成STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表,而shutdown只是将线程池的状态设置成SHUTDOWN状态,然后中断所有没有正在执行任务的线程。

只要调用了这两个关闭方法的其中一个,isShutdown方法就会返回true。当所有的任务都已关闭后,才表示线程池关闭成功,这时调用isTerminaed方法会返回true。至于我们应该调用哪一种方法来关闭线程池,应该由提交到线程池的任务特性决定,通常调用shutdown来关闭线程池,如果任务不一定要执行完,则可以调用shutdownNow。

时间: 2024-10-07 21:55:05

线程学习四:线程池的相关文章

java多线程学习(四)——线程的交互

线程交互中用到的三个基本函数: void notify():唤醒在此对象监视器上等待的单个线程. void notifyAll():唤醒在此对象监视器上等待的所有线程. void wait();导致当前的线程等待,直到其他线程调用此对象的notify()或者notifyAll()方法. void wait(long timeout);wait()的重载版本,同样导致当前线程等待,直到其他线程调用此对象的notify()或者notifyAll()方法,或者等待超过指定的时间后不再等待. void

C# 线程--第四线程实例

概述 在前面几节中和大家分享了线程的一些基础使用方法,本章结合之前的分享来编写一些日常开发中应用实例,和编写多线程时一些注意点.如大家有好的实例也欢迎分享.. 应用实例 应用:定时任务程序 场景:系统中常常会有一些需要定时去循环执行的存储过程或方法等,这时就出现了定时任务小程序. 模型:查询需定时执行的计划任务-->插入线程池-->执行任务 static void MainMethod() { Thread thead; thead = new Thread(QueryTask); thead

nginx 学习四 内存池 ngx_pool_t 和内存管理操作

这几天在看nginx,发现凡是有内存申请的地方都有pool这个东东出现,仔细看看,原来pool的类型是ngx_pool_t,是nginx用来做内存管理的,于是就决定看看他的实现. 1 nginx内存池相关的结构体 ngx_pool_t定义在core/ngx_palloc.h ngx_palloc.c中,下面是几个主要的结构体 ngx_pool_data_t typedef struct { //内存池的数据结构模块 u_char *last; //当前内存分配结束位置,即下一段可分配内存的起始位

Java多线程(四) 线程池

一个优秀的软件不会随意的创建很销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理. JDK提供了四种不同的线程池给程序员使用 首先使用线程池,需要用到ExecutorService接口,该接口有个抽象类AbstractExecutorService对其进行了实现,ThreadPoolExecutor进一步对抽象类进行了实现.最后JDK封装了一个Executor类对ThreadP

多线程编程学习笔记——线程池(一)

接上文 多线程编程学习笔记——线程同步(一) 接上文 多线程编程学习笔记——线程同步(二) 接上文 多线程编程学习笔记——线程同步(三) 创建多线程操作是非常昂贵的,所以每个运行时间非常短的操作,创建多线程进行操作,可能并不能提高效率,反而降低了效率. 如果你有非常多的执行时间非常短的操作,那么适合作用线程池来提高效率,而不是自行创建多线程. 线程池,就是我们先分配一些资源到池子里,当我们需要使用时,则从池子中获取,用完了,再放回池子里. .NET中的线程池是受CLR管理的,TheadTool类

从使用到原理学习Java线程池

来源:SilenceDut http://www.codeceo.com/article/java-threadpool-learn.html 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. 所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务就是一个需要解决的关键问题,其实这

深入学习Java线程池

在前面的例子中,我们都是通过new Thread来创建一个线程,由于线程的创建和销毁都需要消耗一定的CPU资源,所以在高并发下这种创建线程的方式将严重影响代码执行效率.而线程池的作用就是让一个线程执行结束后不马上销毁,继续执行新的任务,这样就节省了不断创建线程和销毁线程的开销. ThreadPoolExecutor 创建Java线程池最为核心的类为ThreadPoolExecutor: 它提供了四种构造函数来创建线程池,其中最为核心的构造函数如下所示: 1234567 public Thread

C#多线程学习 之 线程池[ThreadPool](转)

在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPool(线程池)来解决: 另一种情况:线程平时都处于休眠状态,只是周期性地被唤醒                   这一般使用Timer(定时器)来解决: 本篇文章单单讲线程池[ThreadPool] ThreadPool类 MSDN帮助信息: http://msdn.microsoft.com/z

Java并发包源码学习之线程池(一)ThreadPoolExecutor源码分析

Java中使用线程池技术一般都是使用Executors这个工厂类,它提供了非常简单方法来创建各种类型的线程池: public static ExecutorService newFixedThreadPool(int nThreads) public static ExecutorService newSingleThreadExecutor() public static ExecutorService newCachedThreadPool() public static Scheduled