




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、为什么引入Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪。不利于扩展,比如如定时执行、定期执行、线程中断采用线程池的优点 重用存在的线程,减少对象创建、消亡的开销,性能佳可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞提供定时执行、定期执行、单线程、并发数控制等功能Executor的介绍 在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Ja
2、va 5中引入的, 其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逃逸问题如果我们在构造器中启动一个线程,因为另一个任务可能会在构造器结束之前开始执行,此时可能会访问到初始化了一半的对象用Executor在构造器中。Executor框架包括:线程池,Executor,Executors,ExecutorService,Com
3、pletionService,Future,Callable等。Executors方法介绍 Executors工厂类 通过Executors提供四种线程池,newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool。推荐精选1.public static ExecutorService newFixedThreadPool(int nThreads)创建固定数目线程的线程池。2.public static ExecutorService newCachedThreadPool()创建
4、一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线 程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。3.public static ExecutorService newSingleThreadExecutor()创建一个单线程化的Executor。4.public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。1.newFixedTh
5、readPool创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。 示例 ExecutorService executorService = Executors.newFixedThreadPool(5); for (int i = 0; i < 20; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.execute(syncRunnable); 运行结
6、果:总共只会创建5个线程, 开始执行五个线程,当五个线程都处于活动状态,再次提交的任务都会加入队列等到其他线程运行结束,当线程处于空闲状态时会被下一个任务复用2.newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程 示例: ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i+) 推荐精选 Runnable syncRunnable = new Runnable() Override public vo
7、id run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.execute(syncRunnable); 运行结果:可以看出缓存线程池大小是不定值,可以需要创建不同数量的线程,在使用缓存型池时,先查看池中有没有以前创建的线程,如果有,就复用.如果没有,就新建新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务3.newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行 schedule(Runnable command,long delay, TimeUnit un
8、it)创建并执行在给定延迟后启用的一次性操作示例:表示从提交任务开始计时,5000毫秒后执行 ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); for (int i = 0; i < 20; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.schedule(sync
9、Runnable, 5000, TimeUnit.MILLISECONDS); 运行结果和newFixedThreadPool类似,不同的是newScheduledThreadPool是延时一定时间之后才执行scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnitunit) 推荐精选创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在initialDelay+period 后执行,接着在 initialDelay +
10、2 * period 后执行,依此类推 ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.scheduleAtFixedRate(syncRunnable, 5000, 3000, TimeUnit.MILLISECONDS);sc
11、heduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟 ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thr
12、ead.currentThread().getName(); try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace(); ; executorService.scheduleWithFixedDelay(syncRunnable, 5000, 3000, TimeUnit.MILLISECONDS);4.newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行 ExecutorService
13、executorService = Executors.newSingleThreadExecutor();推荐精选 for (int i = 0; i < 20; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.execute(syncRunnable); 运行结果:只会创建一个线程,当上一个执行完之后才会执行第二个ExecutorService ExecutorServ
14、ice是一个接口,ExecutorService接口继承了Executor接口,定义了一些生命周期的方法。 public interface ExecutorService extends Executor void shutdown();/顺次地关闭ExecutorService,停止接收新的任务,等待所有已经提交的任务执行完毕之后,关闭ExecutorService List<Runnable> shutdownNow();/阻止等待任务启动并试图停止当前正在执行的任务,停止接收新的任务,返回处于等待的任务列表 boolean isShutdown();/判断线程池是否已经关闭
15、 boolean isTerminated();/如果关闭后所有任务都已完成,则返回 true。注意,除非首先调用 shutdown 或 shutdownNow,否则 isTerminated 永不为 true。 boolean awaitTermination(long timeout, TimeUnit unit)/等待(阻塞)直到关闭或最长等待时间或发生中断,timeout - 最长等待时间 ,unit - timeout 参数的时间单位 如果此执行程序终止,则返回 true;如果终止前超时期满,则返回 false <T> Future<T> submit(Cal
16、lable<T> task);/提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get 方法在成功完成时将会返回该任务的结果。 <T> Future<T> submit(Runnable task, T result);/提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功完成时将会返回给定的结果。推荐精选 Future<?> submit(Runnable task);/提交一个 Runnable 任务用于执行,并返回一个表示该任
17、务的 Future。该 Future 的 get 方法在成功 完成时将会返回 null <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)/执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone() 为 true。 throws InterruptedException; <T> List<Future<T>> invokeAll(Col
18、lection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)/执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone() 为 true。 throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks)/执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回
19、其结果。一旦正常或异常返回后,则取消尚未完成的任务。 throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;ExecutorService接口继承自Executor接口,它提供了更丰富的实现多线程的方法,比如,Exe
20、cutorService提供了关闭自己的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。 可以调用ExecutorService的shutdown()方法来平滑地关闭 ExecutorService,调用该方法后,将导致ExecutorService停止接受任何新的任务且等待已经提交的任务执行完成(已经提交的任务会分两类:一类是已经在执行的,另一类是还没有开始执行的),当所有已经提交的任务执行完毕后将会关闭ExecutorService。因此我们一般用该接口来实现和管理多线程。ExecutorService的生命周期包括三种状态:运行、关闭、终止。创建后便进入运行状态
21、,当调用了shutdown()方法时,便进入关闭状态,此时意味着ExecutorService不再接受新的任务,但它还在执行已经提交了的任务,当素有已经提交了的任务执行完后,便到达终止状态。如果不调用shutdown()方法,ExecutorService会一直处在运行状态,不断接收新的任务,执行新的任务,服务器端一般不需要关闭它,保持一直运行即可。推荐精选Executor执行Runnable任务 一旦Runnable任务传递到execute()方法,该方法便会自动在一个线程上执行。下面是是Executor执行Runnable任务的示例代码:public class TestCachedThr
22、eadPool public static void main(String args) ExecutorService executorService = Executors.newCachedThreadPool(); / ExecutorService executorService = Executors.newFixedThreadPool(5); / ExecutorService executorService = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i+) executorService.
23、execute(new TestRunnable(); System.out.println("* a" + i + " *"); executorService.shutdown(); class TestRunnable implements Runnable public void run() System.out.println(Thread.currentThread().getName() + "线程被调用了。"); 结果 推荐精选Executor执行Callable任务 在Java 5之后,任务分两类:一类是实现了Run
24、nable接口的类,一类是实现了Callable接口的类。两者都可以被ExecutorService执行,但是Runnable任务没有返回值,而Callable任务有返回值。并且Callable的call()方法只能通过ExecutorService的submit(Callable<T> task) 方法来执行,并且返回一个 <T>Future<T>,是表示任务等待完成的 Future。下面给出一个Executor执行Callable任务的示例代码: public class CallableDemo public static void main(Stri
25、ng args) ExecutorService executorService = Executors.newCachedThreadPool(); List<Future<String>> resultList = new ArrayList<Future<String>>(); /创建10个任务并执行 for (int i = 0; i < 10; i+) /使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中 推荐精选 Future<String> future = exec
26、utorService.submit(new TaskWithResult(i); /将任务执行结果存储到List中 resultList.add(future); /遍历任务的结果 for (Future<String> fs : resultList) try while(!fs.isDone);/Future返回如果没有完成,则一直循环等待,直到Future返回完成 System.out.println(fs.get(); /打印各个线程(任务)执行的结果 catch(InterruptedException e) e.printStackTrace(); catch(Exe
27、cutionException e) e.printStackTrace(); finally /启动一次顺序关闭,执行以前提交的任务,但不接受新任务 executorService.shutdown(); class TaskWithResult implements Callable<String> private int id; public TaskWithResult(int id) this.id = id; /* * 任务的具体过程,一旦任务传给ExecutorService的submit方法, * 则该方法自动在一个线程上执行 */ public String ca
28、ll() throws Exception System.out.println("call()方法被自动调用! " + Thread.currentThread().getName(); /该返回结果将被Future的get方法得到 return "call()方法被自动调用,任务返回的结果是:" + id + " " + Thread.currentThread().getName(); 推荐精选 某次执行结果如下: 从结果中可以同样可以看出,submit也是首先选择空闲线程来执行任务,如果没有,才会创建新的线程来执行任务。另外,需要注意:如果Future的返回尚未完成,则get()方法会阻塞等待,直到Future完成返回,可以通过调用isDone()方法判断Future是否完成了返回。自定义线程池 自定义线程池,可以用ThreadPoolExecuto
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 考点28化学反应的方向、化学反应的调控(核心考点精讲精练)-备战2025年高考化学一轮复习考点帮(新高考)(原卷版)
- 考点09钠及其重要化合物(核心考点精讲精练)-备战2025年高考化学一轮复习考点帮(新高考)(原卷版)
- 文化融合2024年国际物流师试题与答案
- 中班防溺水课件及教案
- 中班防溺水游戏课件教案
- 国际物流结算与支付知识试题及答案
- 2024年CPSM考生必须掌握的技能试题及答案
- 2024年CPMM有效策略试题及答案
- 云南省曲靖市宣威市民中2025届高考化学二模试卷含解析
- 2025年高品质H酸项目合作计划书
- 耳鼻咽喉试题及参考答案
- 2025年化学品运输车辆租赁合同范例
- 神经外科重症护理课件
- 2025年甘肃省安全员B证考试题库及答案
- 全国网络安全行业职业技能大赛(网络安全管理员)考试题及答案
- 现场材料进场验收培训
- 图神经网络前沿-深度研究
- 斯大林格勒保卫战
- 质量控制与制造工艺
- 2025年诸暨市水务集团有限公司招聘笔试参考题库含答案解析
- 幼儿园服务培训
评论
0/150
提交评论