繁体   English   中英

在这种情况下,如何有效使用线程?

[英]How can I efficiently use threads in this case?

我必须使用线程将彩票产生的所有可能组合写入文件中。 例:

  1. 0 0 0 0 0 0(第一个组合)
  2. 0 0 0 0 0 1 1(第二组合)
  3. 0 0 0 0 0 2

    持续。 38 38 38 38 38 38(最后组合)

在我的主类中,我只使用一个线程,因为我不知道如何使用更多线程更快地写入文件。

为了生成数字,我使用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();
        }

    }


}

另外文件(在执行过程中)的大小增加了8GB,我必须停止它,因为我的PC崩溃了。

编辑:如果我不能这样做,至少我可以几乎同时在同一文件中使用两个不同的线程进行写操作? 如果我能做到那我该怎么办?

您从停止开始。 认真地:退一步。

首先,由于tkausl正确地进行了注释,因此当您的瓶颈是IO性能时,使用多个线程可能无济于事。 相反,让多个线程写入同一个文件可能并没有帮助。 此外, 很难做到这一点!

因此,如果有的话,您将不得不考虑将此任务分配到多个系统上。 然后我们调查您的代码; 很明显,您无法使用此类代码执行此操作。

那是我的初衷:您的代码是非常底层的。 那里几乎没有将任务中的不同活动彼此分离的抽象。 循环内循环。 那是可能“完成”其工作的代码(或者,如果“预期”的输出会更小)。 但是它不包含将其“适应”实际需求所需的任何有用的抽象。

长话短说:如果您真的想尝试多线程的东西; 然后将您的代码变成基于的解决方案。 然后,如果可行,您可以研究并行流; 并使用它们来“并行”运行代码。

仅作记录: 代码中存在错误

linea.append(i + " " +j + " " +j2 + " " +k + " " +k2 + " " +l + "\n");
bw.write(linea.toString())

会将新行添加到缓冲区; 然后写入整个缓冲区。 但是:这些行保留在您的缓冲区中!

因此,也许在这种情况下,“简单”的答案是:在写入缓冲区内容之后清除缓冲区! 如: 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时间来写和读。 您知道,“ IO”仍然是最昂贵的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM