Lu *_*MON 0 java performance multithreading combinations thread-safety
我必须在文件中写入使用线程的彩票产生的所有可能组合.例:
在我的主类我只使用一个线程,因为我不知道如何更快地使用更多线程写入文件.
为了生成数字,我使用6个循环,一个在另一个内部,这样:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;
public class Proceso extends Thread {
File file = new File("lottery.txt");
public Proceso(String msg) {
super(msg);
}
public void run() {
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
StringBuffer linea = new StringBuffer();
for (int i = 0; i < 15;i++) {
for (int j = 0; j < 39; j++) {
for (int j2 =0; j2 < 39; j2++) {
for (int k = 0; k < 39; k++) {
for (int k2 = 0 ; k2 < 39; k2++) {
for (int l = 0; l < 39; l++) {
linea.append(i + " " +j + " " +j2 + " " +k + " " +k2 + " " +l + "\n");
bw.write(linea.toString());
}
}
}
}
}
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,文件(在执行的中间)增加了8GB的大小,我必须停止它因为我的电脑崩溃.
编辑:如果我不能这样做,至少我几乎可以同时在同一个文件中用两个不同的线程写?如果我能做到这一点,我会怎么做?
你从停止开始.说真的:退一步.
首先,由于tkausl正确评论,当您的瓶颈是IO性能时,使用多个线程可能无济于事.相反 - 将多个线程写入同一文件可能并非全部有用.此外,很难做到这一点!
因此,如果有的话,您将不得不考虑将此任务分配到多个系统上.然后我们查看您的代码; 很明显,你不能用这样的代码做到这一点.
这是我最初的观点:你的代码非常低级.几乎没有抽象可以将这项任务中的不同活动彼此分开.只需在循环内循环循环.这是可能"完成"其工作的代码(或者如果"预期"输出会更小,则可能会这样做); 但它不包含任何有用的抽象,你需要"适应"它的实际需要.
长话短说:如果你真的想尝试多线程的东西; 然后从将代码转换为基于流的解决方案开始.然后,当它工作时,你可以研究并行流; 并使用它们"并行"运行代码.
仅供记录:您的代码中存在错误.
linea.append(i + " " +j + " " +j2 + " " +k + " " +k2 + " " +l + "\n");
bw.write(linea.toString())
Run Code Online (Sandbox Code Playgroud)
这会在缓冲区中添加一个新行; 然后写入整个缓冲区.但是:线条留在你的缓冲区!
所以,也许在这种情况下,"简单"的答案是:在你写完内容后清除缓冲区!喜欢:linea.delete(0, linea.length()).顺便说一句:使用StringBuilder; 不是StringBuffer.您只需为每一行创建一个新构建器(而不是一直使用/清除同一构建器).
很可能你得到了你的异常,因为你的StringBuffer不断增长和增长; 直到你的内存耗尽.
最后的注意事项:退步仍然是这里要做的事情.如果我没有弄错的话,你打算创建的文件将有38*38*38*38*38*38行,即3.010.936.384,大约有30亿个条目.假设每行包含10,15个字节.所以你最终得到一个大约30 GB左右的文件.但为什么?该文件将包含这些值的简单排列.通过一些数学运算......单独的行号可用于计算在该行中找到的字符串!因为您可以将1到3.010.936.384之间的任何值映射到相应的"置换".
因此,更长的故事简短:无论什么程序使用30 GB文件 - 它都不需要.你知道存在多少种排列; 并且您可以轻松地计算(也就是预测)排列.任何需要这些排列的程序都可以做到!如果您可以轻松地计算数据,那么将30 GB的数据写入文件系统是没有意义的!
因此,实质上:忘记将这些东西写入文件.你没有.这只会花费你以后的写作和阅读时间.你知道,"IO"仍然是最昂贵的事情.