我希望多次写入文件(100k+),写入将通过不稳定的网络进行。所以要做到这一点,我正在考虑使用 JavaExecutorService
来帮助生成线程,但我不太确定哪种设置组合会正确地发生以下情况:
- 一次只允许 1 次写入(当然顺序很重要)
- 允许写入有足够的时间进行每次写入(比如 5 秒),此时只需保释即可
- 如果写入缓慢,让 Executor 将写入收集到队列中并等待。
- 在线程队列为空之前,不要让整个程序退出。
- 由作者分隔线程。即,如果相同的写入器出现在此函数中,则将其放入自己的队列中。如果有不同的写入器指针进入,则给它自己的队列(无需将不同的写入器放在同一个队列中)。
我相信这可以通过结合执行器功能以及主程序对象上的.wait()
and命令来完成。.notify()
但是,我只是不确定如何精确地使用 executor API 来完成这项工作。
这是我得到的:
private void writeToFileInSeperateThread(final PrintWriter writer, final String text) {
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
executor.submit(new Thread(new Runnable() {
public void run() {
writer.println(text);
}
})).get(5L, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
}
该方法将在单个进程中被调用 100k+ 次,所以我不确定我是否应该ExcutorService
每次都创建一个新实例,还是使用同一个实例?(在我尝试使用相同的方法时,我不断收到我认为与.newSingleThreadExecutor()
指令有关的异常。
希望保持 Java 5 兼容,但 Java 6 没问题。在 Windows XP/7 上运行。
更新:这似乎在初始测试中起到了作用:
private class WriterStringPair {
public final PrintWriter writer;
public final String text;
public WriterStringPair(PrintWriter writer, String text) {
this.writer = writer;
this.text = text;
}
}
private void writeTextInSeperateThread(Writer writer, String text) {
try {
textQueue.offer(new WriterStringPair(writer, text), 300L, TimeUnit.SECONDS);
} catch (InterruptedException e) {
errOut.println(e);
e.printStackTrace();
}
}
final BlockingQueue<WriterStringPair> textQueue = new ArrayBlockingQueue<WriterStringPair>(500);
private void setWritingThread() {
new Thread((new Runnable() {
public void run() {
WriterStringPair q;
while (!shutdown && !Thread.currentThread().isInterrupted()) {
try {
q = textQueue.poll(1L, TimeUnit.SECONDS);
if (q != null) {
q.writer.write(q.text + "\n");
q.writer.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
})).start();
}