昨天晚上做了个实验,用多个线程复制7个文件和单个线程复制7个文件(总共约1.7G)比较,代码如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class T3 {
public static void main(String[] args) throws IOException, InterruptedException {
File path = new File("E:\\tmp\\1");
File[] listFiles = path.listFiles();
ExecutorService exec=Executors.newFixedThreadPool(listFiles.length);
CountDownLatch c = new CountDownLatch(listFiles.length);
System.out.println("begin copy");
long b=System.nanoTime();
one(listFiles,c);
// two(listFiles, exec,c);
c.await();
long n=System.nanoTime();
System.out.println("copy over,times="+(n-b));
}
public static void one(File[] listFiles,CountDownLatch c) throws IOException{
for(File f:listFiles){
FileInputStream fis=null;
FileOutputStream fos=null;
try{
fis = new FileInputStream(f);
fos = new FileOutputStream(new File("c://tmp//"+f.getName()));
byte[] bs=new byte[1024*1024*10];
int n=-1;
while((n=fis.read(bs))>0){
fos.write(bs, 0, n);
}
}finally{
if(fis!=null) fis.close();
if(fos!=null) fos.close();
System.out.println(Thread.currentThread().getName()+" copy "+f.getName()+" ok");
c.countDown();
}
}
}
public static void two(File[] files,ExecutorService exec,CountDownLatch c){
for(File f:files){
// exec.execute(new R(f,c));
new Thread(new R(f,c)).start();
}
exec.shutdown();
}
}
class R implements Runnable{
private File f;
private CountDownLatch c;
public R(File f,CountDownLatch c){
this.f=f;this.c=c;
}
@Override
public void run() {
FileInputStream fis=null;
FileOutputStream fos=null;
try{
fis = new FileInputStream(f);
fos = new FileOutputStream(new File("c://tmp//"+f.getName()));
byte[] bs=new byte[1024*1024];
int n=-1;
while((n=fis.read(bs))>0){
fos.write(bs, 0, n);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(fis!=null) fis.close();
if(fos!=null) fos.close();
}catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" copy "+f.getName()+" ok");
c.countDown();
}
}
}
多线程明显比单线程慢很多。
打开任务管理器,单线程情况下,磁盘利用率已经99了,读写速度90M/s,于是降低读写速度byte[] bs=new byte[100];再次比较。单线程 磁盘利用率已经变为20左右,读写速度降到了20M/s. 多线程起初IO读写速度较高,但是7个线程都io的时候,利用率达到了99,读写速度受到限制,但是最后随着有的线程完成了任务,io读写速度又升上去了,最终多线程复制话费的时间少于单线程。
因此想要多线程复制文件,要考虑IO读写速度,单线程磁盘利用率100了,再增加线程也没用。