JAVA线程池Executor的简单使用
来源:互联网 发布:支付宝能解绑淘宝号码 编辑:程序博客网 时间:2024/05/18 02:58
在JDK1.5之前,如果需要使用线程池,需要自己动手写代码实现,这对于初学者来说,不是一件容易的事。JDK1.5提供了Executor类,用户通过它可得到各种类型的线程池。
Executor提供的线程池,可以分为:固定尺寸的线程池、可变尺寸的线程池。
Executor.java提供部分接口
public static ExecutorService newFixedThreadPool(int nThreads)创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。public static ExecutorService newSingleThreadExecutor()创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。public static ExecutorService newCachedThreadPool()创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。public static ScheduledExecutorService newSingleThreadScheduledExecutor()创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
public static ExecutorService newFixedThreadPool(int n),线程池中有n个线程,如果实际线程数m,m>n,则先加入的前n个线程,先执行,处于执行状态,后加入的m-n个线程,处于阻塞状态,直到有某个线程执行完了,则处于阻塞状态的线程中的其中一个启动。也就是说最多同时n个线程处于执行状态。
package thread;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolTest {public static void main(String[] args) {ExecutorService executorService=Executors.newFixedThreadPool(3);MyThread a=new MyThread("A");MyThread b=new MyThread("B");MyThread c=new MyThread("C");MyThread d=new MyThread("D");executorService.execute(a);executorService.execute(b);executorService.execute(c);executorService.execute(d);executorService.shutdown();}static class MyThread implements Runnable{private String name;public MyThread(String name){this.name=name;}@Overridepublic void run(){for(int i=1;i<=5;i++){System.out.println(this.name+"第"+i+"次运行.........");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}}
运行结果
B第1次运行.........
C第1次运行.........
A第1次运行.........
B第2次运行.........
C第2次运行.........
A第2次运行.........
B第3次运行.........
C第3次运行.........
A第3次运行.........
B第4次运行.........
C第4次运行.........
A第4次运行.........
B第5次运行.........
C第5次运行.........
A第5次运行.........
D第1次运行.........
D第2次运行.........
D第3次运行.........
D第4次运行.........
D第5次运行.........
ABC同时启动,所以打印顺序是混乱的;最后有空闲线程资源执行D时,只有它在执行,所以看上去有序。
public static ExecutorService newSingleThreadExecutor()线程池中的线程数为1,如果实际线程数大于1时,则按照加入的顺序按顺序执行。所以如果开发中遇到多个线程一个个执行(前一个执行完后,后一个才能执行)的话,可以使用这种方式就可以避免使用join()方法,一个个控制了。
将上面程序获得线程池的语句修改一下。
//ExecutorService executorService=Executors.newFixedThreadPool(3);ExecutorService executorService=Executors.newSingleThreadExecutor();
运行结果A第1次运行.........
A第2次运行.........
A第3次运行.........
A第4次运行.........
A第5次运行.........
B第1次运行.........
B第2次运行.........
B第3次运行.........
B第4次运行.........
B第5次运行.........
C第1次运行.........
C第2次运行.........
C第3次运行.........
C第4次运行.........
C第5次运行.........
D第1次运行.........
D第2次运行.........
D第3次运行.........
D第4次运行.........
D第5次运行.........
运行结果是有序的。
public static ExecutorService newCachedThreadPool()动态创建线程数,如果新加入一个线程任务,当前线程池中没有空闲的线程,则新创建一个线程用来执行新任务;如果有空闲线程,则使用空闲线程。一个线程的任务执行完后,线程状态成为空闲状态,线程不会立即销毁,60秒后,如果没有新任务进来,则空闲线程(空闲时间已达到60s)就销毁.
将上面程序获取线程池的语句修改下。
//ExecutorService executorService=Executors.newFixedThreadPool(3);//ExecutorService executorService=Executors.newSingleThreadExecutor();ExecutorService executorService=Executors.newCachedThreadPool();
运行结果B第1次运行.........
D第1次运行.........
A第1次运行.........
C第1次运行.........
B第2次运行.........
D第2次运行.........
A第2次运行.........
C第2次运行.........
B第3次运行.........
D第3次运行.........
A第3次运行.........
C第3次运行.........
D第4次运行.........
B第4次运行.........
A第4次运行.........
C第4次运行.........
B第5次运行.........
D第5次运行.........
A第5次运行.........
C第5次运行.........
ABCD的运行是混乱的。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize),看方法名就知道,该线程池可以执行定时任务。
package thread;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ThreadPoolTest {public static void main(String[] args) {ScheduledExecutorService executorService=Executors.newScheduledThreadPool(3);MyThread a=new MyThread("A");MyThread b=new MyThread("B");MyThread c=new MyThread("C");MyThread d=new MyThread("D");executorService.schedule(a, 1000, TimeUnit.MILLISECONDS);//1000毫秒后执行executorService.schedule(b, 500, TimeUnit.MILLISECONDS);//500ms后执行executorService.schedule(c, 1, TimeUnit.SECONDS);//1s后执行executorService.schedule(d, 1, TimeUnit.SECONDS);executorService.shutdown();}static class MyThread implements Runnable{private String name;public MyThread(String name){this.name=name;}@Overridepublic void run(){for(int i=1;i<=3;i++) System.out.println(name+"在执行第"+i+"次....."+new SimpleDateFormat("hh:mm:ss").format(new Date()));}}}
运行结果
B在执行第1次.....08:20:16
B在执行第2次.....08:20:16
B在执行第3次.....08:20:16
A在执行第1次.....08:20:17
A在执行第2次.....08:20:17
A在执行第3次.....08:20:17
C在执行第1次.....08:20:17
C在执行第2次.....08:20:17
C在执行第3次.....08:20:17
D在执行第1次.....08:20:17
D在执行第2次.....08:20:17
D在执行第3次.....08:20:17
至于public static ScheduledExecutorService newSingleThreadScheduledExecutor(),读者可以将上面程序修改下就OK了。
运行结果
B在执行第1次.....08:25:08
B在执行第2次.....08:25:08
B在执行第3次.....08:25:08
A在执行第1次.....08:25:09
A在执行第2次.....08:25:09
A在执行第3次.....08:25:09
C在执行第1次.....08:25:09
C在执行第2次.....08:25:09
C在执行第3次.....08:25:09
D在执行第1次.....08:25:09
D在执行第2次.....08:25:09
D在执行第3次.....08:25:09
- JAVA线程池Executor的简单使用
- Java 线程池(threads pool), Executor 的使用
- Java线程池自学手册Executor的使用
- java线程池Executor,ExecutorService,ThreadPoolExecutor的使用
- java线程池Executor
- Java 线程池(Executor)
- Java 线程池-Executor
- Java 线程池(一)---Executor
- 《Java线程池》:Executor生命周期
- java线程池框架Executor
- 《Java线程池》:Executor生命周期
- 【Java 并发】Executor框架机制与线程池配置使用
- Java并发编程——Executor接口及线程池的使用
- Java并发编程——Executor接口及线程池的使用
- Executor框架的线程池
- Java线程Executor框架详解与使用
- Java 线程 Executor 框架详解与使用
- Java 线程 Executor 框架详解与使用
- python 学习笔记(10)重构与文件处理
- Dog -Piling:缓存失效遇上大量访问
- ZOJ3705Applications(浙江省第十届省赛)
- Web3.0概述
- 智力1
- JAVA线程池Executor的简单使用
- 关于widthStep造成的问题
- C++动态创建二维数组
- Reverse a positive number
- 微软SQLHelper.cs类 中文版 笔记
- Tower of Hanoi
- 第六章 面向对象的程序设计(二) JavaScript高级程序设计
- I2c通信问题分析(欢迎高手补充)
- 杭电2047