并发编程:fork/join框架:异步地运行任务(CountedCompleter)

目录

CountedCompleter

案例说明

一、主程序

二、统计任务

三、执行结果


CountedCompleter

  1. onCompletion()。使用这个任务类时,可以加入一个完成方法(onCompletion()方法),当程序调用tryComplete方法且没有子任务时,会执行该方法。(即要重写onCompletion方法)
  2. getRawResult(),返回执行结果用。当任务调用join()方法时,会返回getRawResult()的结果。(即要重写getRawResult方法)

案例说明

分别搜索并统计3个目录下的指定文件的数量

一、主程序

package xyz.jangle.thread.test.n5_4.countedcompleter;

import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

/**
 * 5.4、异步的运行任务CountedCompleter
 * 	分别搜索并统计3个目录下的指定文件的数量
 * @author jangle
 * @email [email protected]
 * @time 2020年8月28日 下午7:11:53
 * 
 */
public class M {

	public static void main(String[] args) {

		ForkJoinPool pool = new ForkJoinPool();
		FolderProcessor folderProcessor = new FolderProcessor("C:\\workspace", "java");
		FolderProcessor folderProcessor2 = new FolderProcessor("C:\\Windows", "log");
		FolderProcessor folderProcessor3 = new FolderProcessor("C:\\Program Files", "log");
		pool.execute(folderProcessor);
		pool.execute(folderProcessor2);
		pool.execute(folderProcessor3);
		do {
			System.out.println("***********************");
			System.out.println("Main:Active Thread活跃的线程数:" + pool.getActiveThreadCount());
			System.out.println("Main:Task Count任务数:" + pool.getQueuedTaskCount());
			System.out.println("Main:Steal Count线程窃取数量:" + pool.getStealCount());
			System.out.println("***********************");
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (!(folderProcessor.isDone() && folderProcessor2.isDone() && folderProcessor3.isDone()));
		pool.shutdown();
		List results;
		results = folderProcessor.join();
		System.out.println("workspace总共有" + results.size() + "个java文件");
		results = folderProcessor2.join();
		System.out.println("Windows总共有"+results.size()+"个log文件");
		results = folderProcessor3.join();
		System.out.println("Program Files"+results.size()+"个log文件");

	}

}

二、统计任务

package xyz.jangle.thread.test.n5_4.countedcompleter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountedCompleter;

/**
 * 统计目录下指定文件类型的数目 compute()执行计算过程 getRawResult()返回计算结果
 * 
 * @author jangle
 * @email [email protected]
 * @time 2020年8月28日 下午7:20:10
 * 
 */
public class FolderProcessor extends CountedCompleter> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// 路径
	private String path;
	// 文件类型
	private String extension;
	// 子任务列表
	private List tasks;
	// 结果列表
	private List resultList;

	/**
	 * 	 用于在生成子任务时进行构建
	 * @param completer
	 * @param path
	 * @param extension
	 */
	protected FolderProcessor(CountedCompleter completer, String path, String extension) {
		super(completer);
		this.path = path;
		this.extension = extension;
	}

	/**
	 *  初始任务的构建
	 * @param path
	 * @param extension
	 */
	public FolderProcessor(String path, String extension) {
		this.path = path;
		this.extension = extension;
	}

	@Override
	public void compute() {
		resultList = new ArrayList<>();
		tasks = new ArrayList<>();
		File file = new File(path);
		File[] content = file.listFiles();
		if (content != null) {
			for (int i = 0; i < content.length; i++) {
				if (content[i].isDirectory()) {
					// 如果是目录,则创建子任务进行处理(子任务需将当前对象进行传入)
					FolderProcessor task = new FolderProcessor(this, content[i].getAbsolutePath(), extension);
					// 异步执行
					task.fork();
					// 111
					addToPendingCount(1);
					// 将任务添加到子任务列表中
					tasks.add(task);
				} else {
					// 否则是文件,则验证是否为目标扩展名
					if (checkFile(content[i].getName())) {
						resultList.add(content[i].getAbsolutePath());
					}
				}
			}
			if (tasks.size() > 50) {
				System.out.println(file.getAbsolutePath() + "子任务大于50:" + tasks.size());
			}
		}
		// 对任务进行完成操作,如果不执行,会导致任务的isDone()始终为false。
		tryComplete();
	}

	@Override
	public void onCompletion(CountedCompleter caller) {
		for (FolderProcessor childTask : tasks) {
			// 把子任务的结果全部添加到其父级任务中。
			resultList.addAll(childTask.getResultList());
		}
	}

	/**
	 * 该方法用于返回计算结果,不重写的话,程序调用task.join()方法会得到null
	 */
	@Override
	public List getRawResult() {
		return resultList;
	}

	private boolean checkFile(String name) {
		return name.endsWith(extension);
	}

	public List getResultList() {
		return resultList;
	}

}

三、执行结果

***********************
Main:Active Thread活跃的线程数:2
Main:Task Count任务数:0
Main:Steal Count线程窃取数量:0
***********************
C:\Windows子任务大于50:80
C:\Windows\assembly\NativeImages_v4.0.30319_64子任务大于50:118
C:\workspace\.metadata\.plugins子任务大于50:63
C:\Windows\assembly\NativeImages_v4.0.30319_32子任务大于50:65
C:\Program Files\nodejs\node_modules\npm\node_modules子任务大于50:369
C:\workspace\.metadata\.plugins\org.eclipse.core.resources\.history子任务大于50:256
C:\workspace\boc-risk\.git\objects子任务大于50:232
C:\Windows\assembly\GAC_MSIL子任务大于50:301
C:\workspace\myTestDemo\.git\objects子任务大于50:203
C:\Program Files\Git\usr\share\perl5\core_perl\unicore\lib子任务大于50:63
C:\Program Files\Java\jdk-11.0.7\legal子任务大于50:71
C:\Program Files\McAfee\MSC子任务大于50:53
C:\Program Files\nodejs\node_modules\npm\docs\public\cli-commands子任务大于50:59
C:\Windows\rescache\_merged子任务大于50:103
C:\Windows\Microsoft.NET\assembly\GAC_MSIL子任务大于50:504
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:9503
Main:Steal Count线程窃取数量:202
***********************
C:\Windows\System32子任务大于50:133
C:\Windows\System32\DriverStore\FileRepository子任务大于50:736
C:\Windows\SysWOW64子任务大于50:97
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules子任务大于50:56
C:\Windows\System32\oobe\info\default子任务大于50:52
C:\Windows\System32\WindowsPowerShell\v1.0\Modules子任务大于50:68
C:\Windows\WinSxS子任务大于50:15759
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:11670
Main:Steal Count线程窃取数量:990
***********************
C:\Windows\WinSxS\Temp\InFlight子任务大于50:204
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:9277
Main:Steal Count线程窃取数量:991
***********************
C:\Windows\WinSxS\Temp\InFlight\bef169e9507bd6010100000064398441子任务大于50:628
C:\Windows\WinSxS\Temp\InFlight\0458991f4e71d601aa030000a0754872子任务大于50:1623
C:\Windows\WinSxS\Temp\InFlight\f35355fe82dcd5018603000048083809子任务大于50:4230
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:6731
Main:Steal Count线程窃取数量:13504
***********************
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:2651
Main:Steal Count线程窃取数量:19813
***********************
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~18362.959.1.9子任务大于50:5418
***********************
Main:Active Thread活跃的线程数:1
Main:Task Count任务数:0
Main:Steal Count线程窃取数量:26161
***********************
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~18362.1016.1.5子任务大于50:5634
workspace总共有682个java文件
Windows总共有137个log文件
Program Files12个log文件

 

你可能感兴趣的:(并发编程,#,JavaBase,#,Fork/Join,java,并发编程)