Welcome 微信登录

首页 / 软件开发 / JAVA / Java并发基础实践:退出任务I

Java并发基础实践:退出任务I2014-08-17 blogjava Jiangshachina计划写一个"Java并发基础实践"系列,算作本人对Java并发学习与实践的简单总结。本文是该系列的第一篇,介绍了退出并发任务的最简单方法。

在一个并发任务被启动之后,不要期望它总是会执行完成。由于时间限制,资源限制,用户操作,甚至是任务中的异常(尤其是运行时异常),...都可能造成任务不能执行完成。如何恰当地退出任务是一个很常见的问题,而且实现方法也不一而足。

1. 任务

创建一个并发任务,递归地获取指定目录下的所有子目录与文件的绝对路径,最后再将这些路径信息保存到一个文件中,如代码清单1所示:

清单1public class FileScanner implements Runnable {private File root = null;private List<String> filePaths = new ArrayList<String>();public FileScanner1(File root) {if (root == null || !root.exists() || !root.isDirectory()) {throw new IllegalArgumentException("root must be legal directory");}this.root = root;}@Overridepublic void run() {travleFiles(root);try {saveFilePaths();} catch (Exception e) {e.printStackTrace();}}private void travleFiles(File parent) {String filePath = parent.getAbsolutePath();filePaths.add(filePath);if (parent.isDirectory()) {File[] children = parent.listFiles();for (File child : children) {travleFiles(child);}}}private void saveFilePaths() throws IOException {FileWriter fos = new FileWriter(new File(root.getAbsoluteFile()+ File.separator + "filePaths.out"));for (String filePath : filePaths) {fos.write(filePath + "
");}fos.close();}}
2. 停止线程

有一个很直接,也很干脆的方式来停止线程,就是调用Thread.stop()方法,如代码清单2所示:

清单2public static void main(String[] args) throws Exception {FileScanner task = new FileScanner(new File("C:"));Thread taskThread = new Thread(task);taskThread.start();TimeUnit.SECONDS.sleep(1);taskThread.stop();}
但是,地球人都知道Thread.stop()在很久很久之前就不推荐使用了。根据官方文档的介绍,该方法存在着固有的不安全性。当停止线程时,将会释放该线程所占有的全部监视锁,这就会造成受这些锁保护的对象的不一致性。在执行清单2的应用程序时,它的运行结果是不确定的。它可能会输出一个文件,其中包含部分的被扫描过的目录和文件。但它也很有可能什么也不输出,因为在执行FileWriter.write()的过程中,可能由于线程停止而造成了I/O异常,使得最终无法得到输出文件。