【发布时间】:2013-08-25 18:14:18
【问题描述】:
我正在处理我的网络服务器访问日志并将处理后的信息存储到我的数据库中。以前,我是单线程进程。完成这个过程花了很长时间。我决定使用并发文件读取来节省执行时间。我使用Executors 线程池实现了这一点。这是我的java代码。
日志文件处理程序
class FileHandler implements Runnable {
private File file;
public FileHandler(File file) {
this.file = file;
}
@Override
public void run() {
try {
byte[] readInputStream = readInputStream(new FileInputStream(file));
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] readInputStream(InputStream in) throws IOException {
//closing the bytearrayoutput stream has no effect. @see java doc.
ByteArrayOutputStream bos = null;
byte[] buffer = new byte[1024];
int bytesRead = -1;
bytesRead = in.read(buffer);
//no input to read.
if(bytesRead == -1) {
return null;
}
bos = new ByteArrayOutputStream(in.available()); //creating output stream with approximate capacity.
bos.write(buffer , 0 , bytesRead);
try {
while((bytesRead = in.read(buffer)) != -1) {
bos.write(buffer , 0 , bytesRead);
}
}finally {
if(in != null) {
in.close();
}
}
return bos.toByteArray();
}
}
并发文件读取
public class AccessLogProcessor {
public static void main(String[] args) {
String[] files = {
"/home/local/ZOHOCORP/bharathi-1397/Downloads/unique-invoice-zuid1.txt" ,
"/home/local/ZOHOCORP/bharathi-1397/Downloads/unique-invoice-zuid.txt"
};
long start = System.currentTimeMillis();
ExecutorService executors = Executors.newFixedThreadPool(files.length);
for(String file : files) {
executors.execute(new FileHandler(new File(file)));
}
executors.shutdown();
while(!executors.isTerminated());
System.out.println("Time Taken by concurrent reading :: "+(System.currentTimeMillis()-start) + " ms ");
}
}
单线程文件读取
public class Test {
public static void main(String[] args) throws FileNotFoundException, IOException {
String[] files = {
"/home/local/ZOHOCORP/bharathi-1397/Downloads/unique-invoice-zuid1.txt" ,
"/home/local/ZOHOCORP/bharathi-1397/Downloads/unique-invoice-zuid.txt"
};
long start = System.currentTimeMillis();
for(String file : files) {
FileHandler.readInputStream(new FileInputStream(file));
}
System.out.println("Time Taken by concurrent reading :: "+(System.currentTimeMillis()-start) + " ms ");
}
}
10轮执行的测试结果
单线程执行:9ms。
并发执行:14 毫秒。
我正在同时读取文件,但为什么耗时大于单线程执行?请纠正我如果我做错了什么?
【问题讨论】:
-
查找上下文切换和I/O资源争用;使用单个物理磁盘,并发访问总是会减慢 I/O
-
@JarrodRoberson ,您能否简要解释一下以使我摆脱困境?
-
“查找
context switching and contention of I/O resources”的哪一部分你不明白?谷歌那个确切的短语。
标签: java multithreading io