Java 用单线程程序比较Fork和Join
我正在尝试开始使用Fork-Join框架来完成一个较小的任务。作为一个启动示例,我尝试复制mp3文件Java 用单线程程序比较Fork和Join,java,multithreading,fork-join,Java,Multithreading,Fork Join,我正在尝试开始使用Fork-Join框架来完成一个较小的任务。作为一个启动示例,我尝试复制mp3文件 import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import jav
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class DeepFileCopier extends RecursiveTask<String>{
/**
*
*/
private static final long serialVersionUID = 1L;
private static Path startingDir = Paths.get("D:\\larsen\\Music\\");
private static List<Path> listOfPaths = new ArrayList<>();
private int start, end;
public static void main(String[] args) throws IOException
{
long startMillis = System.currentTimeMillis();
Files.walkFileTree(startingDir, new CustomFileVisitor());
final DeepFileCopier deepFileCopier = new DeepFileCopier(0,listOfPaths.size());
final ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
pool.invoke(deepFileCopier);
System.out.println("With Fork-Join " + (System.currentTimeMillis() - startMillis));
long secondStartMillis = System.currentTimeMillis();
deepFileCopier.start = 0;
deepFileCopier.end = listOfPaths.size();
deepFileCopier.computeDirectly();
System.out.println("Without Fork-Join " + (System.currentTimeMillis() - secondStartMillis));
}
private static class CustomFileVisitor extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
{
if (file.toString().endsWith(".mp3")) {
listOfPaths.add(file);
}
return FileVisitResult.CONTINUE;
}
}
@Override
protected String compute() {
int length = end-start;
if(length < 4) {
return computeDirectly();
}
int split = length / 2;
final DeepFileCopier firstHalfCopier = new DeepFileCopier(start, start + split);
firstHalfCopier.fork();
final DeepFileCopier secondHalfCopier = new DeepFileCopier(start + split, end);
secondHalfCopier.compute();
firstHalfCopier.join();
return null;
}
private String computeDirectly() {
for(int index = start; index< end; index++) {
Path currentFile = listOfPaths.get(index);
System.out.println("Copying :: " + currentFile.getFileName());
Path targetDir = Paths.get("D:\\Fork-Join Test\\" + currentFile.getFileName());
try {
Files.copy(currentFile, targetDir, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private DeepFileCopier(int start, int end ) {
this.start = start;
this.end = end;
}
}
import java.io.IOException;
导入java.nio.file.FileVisitResult;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.nio.file.path;
导入java.nio.file.SimpleFileVisitor;
导入java.nio.file.StandardCopyOption;
导入java.nio.file.attribute.BasicFileAttributes;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.ForkJoinPool;
导入java.util.concurrent.RecursiveTask;
公共类DeepFileCopier扩展递归任务{
/**
*
*/
私有静态最终长serialVersionUID=1L;
私有静态路径startingDir=Path.get(“D:\\larsen\\Music\\”;
私有静态列表ListofPath=new ArrayList();
私有int开始,结束;
公共静态void main(字符串[]args)引发IOException
{
long startMillis=System.currentTimeMillis();
walkFileTree(startingDir,newcustomfilevisitor());
final DeepFileCopier DeepFileCopier=新的DeepFileCopier(0,ListofPath.size());
最终ForkJoinPool池=新的ForkJoinPool(Runtime.getRuntime().availableProcessors());
调用(deepFileCopier);
System.out.println(“With Fork Join”+(System.currentTimeMillis()-startMillis));
long secondStartMillis=System.currentTimeMillis();
deepFileCopier.start=0;
deepFileCopier.end=listofPath.size();
deepFileCopier.computedDirectly();
System.out.println(“无Fork连接”+(System.currentTimeMillis()-secondStartMillis));
}
私有静态类CustomFileVisitor扩展了SimpleFileVisitor{
@凌驾
公共文件VisitResult visitFile(路径文件,基本文件属性属性属性)引发IOException
{
if(file.toString().endsWith(“.mp3”)){
添加(文件);
}
返回FileVisitResult.CONTINUE;
}
}
@凌驾
受保护的字符串计算(){
int长度=结束-开始;
如果(长度<4){
返回computedDirectly();
}
int split=长度/2;
final DeepFileCopier FirstHalf Copier=新的DeepFileCopier(启动、启动+拆分);
firsthalf复印机。fork();
最终DeepFileCopier secondhalf copier=新的DeepFileCopier(开始+拆分,结束);
secondHalfCopier.compute();
firstHalfCopier.join();
返回null;
}
私有字符串ComputedDirectly(){
for(int index=start;index
在比较我注意到的性能时-
带拨叉连接149714
无叉连接146590
我在一台双核机器上工作。我原以为可以减少50%的工作时间,但使用Fork-Join的部分比单线程方法要多花3秒钟。如果有不正确的地方,请告诉我。您的问题不适合在普通系统上使用多线程。执行时间用于复制所有文件。但这受到硬盘的限制,硬盘会按顺序处理文件 如果您运行的是CPU密集度更高的任务,那么您应该注意到一个差异。出于测试目的,您可以尝试以下操作:
private String computeDirectly() {
Integer nonsense;
for(int index = start; index< end; index++) {
for( int j = 0; j < 1000000; j++ )
nonsense += index*j;
}
return nonsense.toString();
}
With Fork-Join 2628
Without Fork-Join 6421