Java 并发编程之任务取消(六)
来源:互联网 发布:民营医院网络推广 编辑:程序博客网 时间:2024/05/08 12:10
关闭ExecutorService
ExecutorService提供了两种关闭方法,使用Shutdown正常关闭,以及使用ShutdownNow强行关闭。在进行强行关闭时,shutdownNow首先关闭当前正在执行的任务。然后返回所有尚未启动的任务清单 。
返回未启动任务清单这句没明白返回的方式,于是去查看了一下源码
/** * Attempts to stop all actively executing tasks, halts the * processing of waiting tasks, and returns a list of the tasks * that were awaiting execution. * * <p>This method does not wait for actively executing tasks to * terminate. Use {@link #awaitTermination awaitTermination} to * do that. * * <p>There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. For example, typical * implementations will cancel via {@link Thread#interrupt}, so any * task that fails to respond to interrupts may never terminate. * * @return list of tasks that never commenced execution * @throws SecurityException if a security manager exists and * shutting down this ExecutorService may manipulate * threads that the caller is not permitted to modify * because it does not hold {@link * java.lang.RuntimePermission}{@code ("modifyThread")}, * or the security manager's {@code checkAccess} method * denies access. */ List<Runnable> shutdownNow();
是用List的形式返回submit的Runnable
还是像上一篇一样使用日志服务做为栗子
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.RejectedExecutionException;import java.util.concurrent.TimeUnit;public class LogService {private final ExecutorService exec = Executors.newSingleThreadExecutor();private final int TIMEOUT = 100;...public void start() {}public void stop() throws InterruptedException {try {exec.shutdown();exec.awaitTermination(TIMEOUT, TimeUnit.MILLISECONDS);} finally {writer.close();}}public void log(String msg){try{exec.execute(new writerTask(msg)));}catch(RejectedExecutionException ignored){}}}省略了部分代码。因为和上一篇中的代码都一样,主要展现的是利用ExecutorService后Stop方法修改后的样子
毒丸对象
这是另一种消费者生产者的栗子,毒丸是指一个放在队列上的对象 ,其作用是当得到这个对象的时候,立即停止。在FIFO队列中,毒丸对象 将确保消费者在关闭之前首先完成队列中的所有工作。
举个栗子。。。哦。。花了好长时间才调试好。。
import java.io.File;import java.io.FileFilter;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;public class InderXingService {private static final File POISON = new File("");private final IndexerThread consumer = new IndexerThread();private final CrawlerThread producer = new CrawlerThread();private final BlockingQueue<File> queue = new LinkedBlockingQueue<File>();private final FileFilter fileFilter;private final File root = new File("F://Desktop/Open");public static void main(String[] args) {InderXingService index = new InderXingService(null, null);index.start();}public InderXingService(FileFilter fileFilter, File root) {this.fileFilter = fileFilter;}public void start() {producer.start();consumer.start();}public void stop() {producer.interrupt();}public void awaitTermination() throws InterruptedException {consumer.join();}class CrawlerThread extends Thread {@Overridepublic void run() {// TODO Auto-generated method stubtry {crawl(root);} catch (InterruptedException e) {e.printStackTrace();} finally {System.out.println("putpoison");while (true) {try {queue.put(POISON);break;} catch (InterruptedException e1) {}}}}private void crawl(File root) throws InterruptedException {// 为文件添加内容File[] entries = root.listFiles();if (entries != null) {for (File entry : entries) {if (entry.isDirectory()) {crawl(entry.getAbsoluteFile());} else if (!alreadindex(entry)) {queue.put(entry);}}}}private boolean alreadindex(File entry) {// TODO Auto-generated method stubif (queue.contains(entry)) {return true;}return false;}}class IndexerThread extends Thread {@Overridepublic void run() {while (true) {File file;try {file = queue.take();if (file == POISON) {break;} else {indexFile(file);}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}private void indexFile(File root) throws InterruptedException {System.out.println(root.getName());}}}这个是遍历一个目录的文件的栗子-0-
刚才试着遍历了一下整个F盘。。貌似消费者跟的上。而且没啥压力看来都可以用了
public static void main(String[] args) {InderXingService index = new InderXingService(null, null);index.start();try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}index.stop();}试了一下中断方法
UpgradeReport.xslt
UpgradeReport_Minus.gif
UpgradeReport_Plus.gif
java.lang.InterruptedException
putpoison
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(Unknown Source)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.put(Unknown Source)
at InderXingService$CrawlerThread.crawl(InderXingService.java:73)
at InderXingService$CrawlerThread.crawl(InderXingService.java:71)
at InderXingService$CrawlerThread.crawl(InderXingService.java:71)
at InderXingService$CrawlerThread.crawl(InderXingService.java:71)
at InderXingService$CrawlerThread.crawl(InderXingService.java:71)
at InderXingService$CrawlerThread.crawl(InderXingService.java:71)
at InderXingService$CrawlerThread.crawl(InderXingService.java:71)
at InderXingService$CrawlerThread.run(InderXingService.java:49)
结果也对。
使用毒丸君的注意事顶:
只有在生产者和消费者的数量都已知的情况下,才可以使用毒丸对象。当生产者多的时候 ,可以加一个计数器,当所有生产者的丸子都放在队列里边的时候再进行打断。多消费者的时候 ,一个生产者可以放入与消费者数量相同的丸子。因为每个消费者都只能接收一个丸子。当两者数量都比较大时就不太好用了。只有在无界队列中。毒丸对象才能可靠的工作
- Java 并发编程之任务取消(六)
- Java 并发编程之任务取消
- Java 并发编程之任务取消 (二)
- Java 并发编程之任务取消 (三)
- Java 并发编程之任务取消(四)
- Java 并发编程之任务取消(五)
- Java 并发编程之任务取消(七)
- Java 并发编程之任务取消(八)
- Java 并发编程之任务取消(九)
- 任务的取消与关闭(java并发编程实践读书笔记六)
- java并发编程(六)取消与关闭
- JAVA并发编程(四)任务的取消与关闭
- java并发编程实战笔记(二)任务取消
- Java并发系列(六)任务的执行、取消与关闭
- 并发编程7 - 任务取消
- Java并发编程-27-异常处理及取消任务
- 《Java并发编程实战》 任务执行和取消关闭
- Java并发编程实战(学习笔记六 第七章 取消与关闭 上)
- Nand flash
- 2014年8月31日
- Linux企业级项目实践之网络爬虫(21)——扩展为多任务爬虫
- 2014年8月31日
- 解决Delphi 2010启动时出现cannot create xxxx\EditorLineEnds.ttr问题
- Java 并发编程之任务取消(六)
- 2014年8月31日
- 2014年8月31日
- Class类型,选择器Selector以及函数指针
- 编译安装lnmp环境
- 缓冲字符流PW和BR
- storm操作zookeeper源码分析-cluster.clj
- 点滴记录——Ubuntu 14.04中Solr与Tomcat整合安装
- 系统上安装了多种浏览器,能否指定某浏览器访问指定页面: