首先,整个过程的速度只能和最慢的步骤一样快。如果时间分解如下:
通过多线程,你最快也只能在5秒内完成而不是7秒。
其次,不要使用你正在使用的队列,相反尝试复制你正在复制的功能,并使用PipedInputStream
和PipedOutputStream
将进程链接在一起。
编辑:使用Java并发工具处理相关任务有几种方法。将其分成线程。首先创建一个共同的基类:
public interface Worker {
public run(InputStream in, OutputStream out);
}
这个接口代表处理输入并生成输出的任意作业。将它们链接在一起,就形成了一个管道。您也可以抽象出样板文件。为此,我们需要一个类:
public class UnitOfWork implements Runnable {
private final InputStream in;
private final OutputStream out;
private final Worker worker;
public UnitOfWork(InputStream in, OutputStream out, Worker worker) {
if (in == null) {
throw new NullPointerException("in is null");
}
if (out == null) {
throw new NullPointerException("out is null");
}
if (worker == null) {
throw new NullPointerException("worker is null");
}
this.in = in;
this.out = out;
this.worker = worker;
}
public final void run() {
worker.run(in, out);
}
}
比如,Unzip
部分:
public class Unzip implements Worker {
protected void run(InputStream in, OutputStream out) {
...
}
}
类似于Sed
和Zip
等内容。将它们联系在一起的是:
public static void pipe(InputStream in, OutputStream out, Worker... workers) {
if (workers.length == 0) {
throw new IllegalArgumentException("no workers");
}
OutputStream last = null;
List<UnitOfWork> work = new ArrayList<UnitOfWork>(workers.length);
PipedOutputStream last = null;
for (int i=0; i<workers.length-2; i++) {
PipedOutputStream out = new PipedOutputStream();
work.add(new UnitOfWork(
last == null ? in, new PipedInputStream(last), out, workers[i]);
last = out;
}
work.add(new UnitOfWork(new PipedInputStream(last),
out, workers[workers.length-1);
ExecutorService exec = Executors.newFixedThreadPool(work.size());
for (UnitOfWork w : work) {
exec.submit(w);
}
exec.shutdown();
try {
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedExxception e) {
}
}
我不确定你能做得比这更好,而且每个任务需要编写的代码很少。然后你的代码就变成了:
public static processFile(String inputName, String outputName) {
pipe(new FileInputStream(inputFile), new FileOutputStream(outputFile),
new Zip(), new Sed(), new Unzip());
}