Fork/Join机制

化繁为简,分而治之,采用递归

Future机制和FutureTask

可以获取到线程执行的结果,可以中断线程,可以判断任务是否完成。

Fork/Join机制

将任务切割成足够小,最后将结果汇总。

fork决定了ForkJoinTask异步执行,Join任务间结果的汇总。

使用Fork/Join类

(1)继承ForkJoinTask的子类,重写compone 方法,RecursiveAction用于获取没有返回值的方法,RecursiveTask用于获取有返回值的方法。

(2)ForkJoinPool,任务分割的子任务会添加到双端队列中。

如果创建的任务数量过多,对导致内存泄漏

异常处理

isCompletedAbnormally可以检查是否发生异常或者任务是否被取消,可以通过.getException获取具体异常。

//利用ForkJoin统计文件夹下文件的数量

/**
 * 利用Fork/Join统计文件数量
 * @author dwx
 */
public class ForkJoinTest {
	public static void main(String[] args) {
		Integer count =new ForkJoinPool().invoke((new countTask(Paths.get("E:\\33da55214b840df1a95218d36f7e4f2c"))));
		System.out.println("文件总数量"+count);
	}
}

//处理单个目录的任务
class countTask extends RecursiveTask{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Path dir;
	
	public countTask(Path dir) {
		this.dir = dir;
	}

	@Override
	protected Integer compute() {
		int count =0;
		List subTask=new ArrayList();
		try {
			//读取文件的路径
			DirectoryStream ds=Files.newDirectoryStream(dir);
			for (Path path : ds) {
				if(Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
					//对每个子目录都创建新的任务
					subTask.add(new countTask(path));
				}else {
					//不是文件夹加一
					count++;
				}
			}
			if(!subTask.isEmpty()) {
				//调度所有子任务
				for (countTask task : invokeAll(subTask)) {
					count+=task.join();
				}
			}
			return count;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
}

 

你可能感兴趣的:(JAVA并发编程从入门到精通)