약 250K 개의 파일이 들어있는 약 500MB 크기의 zip 파일의 내용을 추출하려고합니다.큰 zip 파일의 내용을 추출하십시오.
"pool-1-thread-7" prio=5 tid=7fd8093dd000 nid=0x11d3f3000 waiting for monitor entry [11d3f2000]
java.lang.Thread.State: BLOCKED (on object monitor)
at de.schlichtherle.truezip.socket.ConcurrentInputShop$SynchronizedConcurrentInputStream.close(ConcurrentInputShop.java:223)
- waiting to lock <785460200> (a de.schlichtherle.truezip.fs.archive.FsDefaultArchiveController$Input)
at de.schlichtherle.truezip.io.DecoratingInputStream.close(DecoratingInputStream.java:79)
at org.apache.commons.io.IOUtils.closeQuietly(IOUtils.java:178)
at ArchiveReaderExecutor$FileExtractorSavor.run(ArchiveReaderExecutor.java:136)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Locked ownable synchronizers:
- <79ed370e0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"pool-1-thread-5" prio=5 tid=7fd8093db800 nid=0x11d1ed000 waiting for monitor entry [11d1ec000]
java.lang.Thread.State: BLOCKED (on object monitor)
at de.schlichtherle.truezip.socket.ConcurrentInputShop$SynchronizedConcurrentInputStream.close(ConcurrentInputShop.java:223)
- waiting to lock <785460200> (a de.schlichtherle.truezip.fs.archive.FsDefaultArchiveController$Input)
at de.schlichtherle.truezip.io.DecoratingInputStream.close(DecoratingInputStream.java:79)
at org.apache.commons.io.IOUtils.closeQuietly(IOUtils.java:178)
at ArchiveReaderExecutor$FileExtractorSavor.run(ArchiveReaderExecutor.java:136)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Locked ownable synchronizers:
- <79ed46468> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
: - 여기
내가 할 노력하고 무엇 나는 동시에이 코드를 실행하고 때,
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileInputStream;
public class ArchiveReaderExecutor {
private final ExecutorService pool;
public ArchiveReaderExecutor() {
pool = Executors.newFixedThreadPool(8);
}
/**
* Splits the archive file into list of lists as provided in the batch size
* variable
*
* @param archive
*
* @return
*/
public List<List<TFile>> splitArchiveFile(final File archive) {
final TFile tFile = new TFile(archive.getAbsolutePath());
final ArrayList<TFile> individualFiles = new ArrayList<TFile>();
recursivelyReadLeafnodes(tFile, individualFiles);
final List<List<TFile>> returnList = new ArrayList<List<TFile>>();
/*
* Splitting the entire list into list of objects for batch processing
*/
int count = 0;
List<TFile> innerList = null;
for (TFile splitFile : individualFiles) {
if (count == 0) {
innerList = new ArrayList<TFile>();
returnList.add(innerList);
}
if (count < 100) {
++count;
} else {
count = 0;
}
innerList.add(splitFile);
}
return returnList;
}
public List<TFile> recursivelyReadLeafnodes(TFile inputTFile,
ArrayList<TFile> individualFiles) {
TFile[] tfiles = null;
if (inputTFile.isArchive() || inputTFile.isDirectory()) {
tfiles = inputTFile.listFiles();
} else {
tfiles = new TFile[0];
tfiles[0] = inputTFile;
}
for (final TFile tFile : tfiles) {
if (tFile.isFile() && !tFile.getName().startsWith(".")) {
individualFiles.add(tFile);
} else if (tFile.isDirectory()) {
recursivelyReadLeafnodes(tFile, individualFiles);
}
}
return individualFiles;
}
public void runExtraction() {
File src = new File("Really_Big_File.zip");
List<List<TFile>> files = splitArchiveFile(src);
for (List<TFile> list : files) {
pool.execute(new FileExtractorSavor(list));
}
pool.shutdown();
}
class FileExtractorSavor implements Runnable{
List<TFile> files;
public FileExtractorSavor(List<TFile> files) {
this.files = files;
}
@Override
public void run() {
File file = null;
TFileInputStream in = null;
for (TFile tFile : files) {
try {
in = new TFileInputStream(tFile);
file = new File("Target_Location"+tFile.getName());
FileUtils.writeStringToFile(file, IOUtils.toString(in));
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(in);
}
}
}
}
public static void main(String[] args) {
new ArchiveReaderExecutor().runExtraction();
}
}
를 대기/차단 된 상태에서 스레드의 많은이 있습니다, 여기에 스레드 덤프입니다 이 단일 스레드에서 실행되면서
TFile.cp_r(src, dst, TArchiveDetector.NULL, TArchiveDetector.NULL);
그것은 훨씬 더 오래 걸렸다 :
또한 사용했습니다.
내 질문에 트루 젝을 사용하여 자바에서 zip 파일의 내용을 추출하는 가장 빠르고, 최적의 방법은 무엇입니까?
차단 된 스레드가 좋지 않다고 생각하는 이유는 무엇입니까? – chrylis
거의 모든 스레드가 수명의 40 % 이상 차단 상태에 있습니다. 이상하지 않습니까? 또한 인플레이션 프로세스는 주어진 유스 케이스와 25K 레코드가 포함 된 50MB 크기의 파일에 대해 약 1 시간이 걸리며 프로세스가 3 분 내에 완료됩니다. 수학에 따르면, 10 배의 파일을 포함하는 더 큰 파일이 30 분 안에 완료되지 않아야합니까? – Shyam
자세한 정보가 없으면 특정 성능 문제에 관해 말할 수 없지만 I/O 집약적 인 응용 프로그램의 스레드가 많이 차단되는 것은 놀라운 일이 아닙니다. – chrylis