0

I have to write in a file all possible combinations resulting from the lottery using threads. Example:

  1. 0 0 0 0 0 0 (first combination)
  2. 0 0 0 0 0 1 (Second combination)
  3. 0 0 0 0 0 2
    . . .
    Last. 38 38 38 38 38 38 (Last combination)

In my main class i just use one thread because i dont know how i can use more threads for write in the file faster.

For generates the numbers i uses 6 loops one inside the other this way:

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();
        }

    }


}

Also the file (in middle of the execution) rise a size of 8gb and i have to stop it because my pc collapse.

Edit: if i cant do that, at least i can write with two different threads in the same file at almost the same time? If i can do that how i would do it?

Lu MON
  • 107
  • 8
  • 3
    You can't use more threads to write faster in a file. Multithreading doesn't speed up IO-bound processes. – tkausl Sep 08 '16 at 04:28
  • @tkausl at least i can write with two different threads in the same file at almost the same time? If i can do that how i would do it? – Lu MON Sep 08 '16 at 04:30
  • Just wondering: all your inner loops go 1 to 38; but the outermost ... just up to 14? Is that on purpose? And maybe, to step back: what will you do with that file? – GhostCat Sep 08 '16 at 04:39
  • Ah, hint: check out my answer again. I think there is a serious bug in your code; that very much explains why you end up with an exception. So you might be able to fix the whole thing; just by fixing that one bug. – GhostCat Sep 08 '16 at 04:43
  • @GhostCat the outerloop has a 14 because i was trying to see if i could let the script run until the end, btw i couldnt, and the file is just there to test multithreading in an IO enviroment (yes i know it sounds crazy but im trying to do a crazy script xD) – Lu MON Sep 08 '16 at 04:44
  • @GhostCat Okay, thanks really! – Lu MON Sep 08 '16 at 04:45
  • @AndreaLuciaPolancoMonero Yet another update to my answer. This time, with the **real message** ;-) – GhostCat Sep 08 '16 at 05:21
  • For the record: I took your "input" and made another question out of that; for the math behind the whole thing: http://stackoverflow.com/questions/39387063/mapping-from-int-to-corresponding-permutation-value ... maybe it is helpful to you. And, if you find my answer here helpful, please dont forget about accepting it. – GhostCat Sep 09 '16 at 07:11
  • @GhostCat, Wow thank you! – Lu MON Sep 09 '16 at 20:56

1 Answers1

5

You start by stopping. Seriously: step back for a second.

First of all, as tkausl is correctly commenting, using more than one thread probably will not help when your bottleneck is IO performance. To the contrary - having multiple threads writing into the same file might not all be helpful. Besides, it is hard to get that right!

So, if at all, you would have to look into distributing this task onto several systems. And we then look into your code; it becomes obvious that you can't do that with such code.

That is my initial point: your code is extremely low-level. There is almost no abstraction in there that would separate the different activities within this task from each other. Just loop within loop within loop. That is code that probably "does" its job (or maybe would, if the "expected" output would be smaller); but it doesn't contain any of the helpful abstractions that you would need to "adapt" it to your actual needs.

Long story short: if you really want to try the multi-threaded thing; then start by turning your code into a stream based solution. And then, when that works, you can study parallel streams; and use those to run your code "in parallel".

And just for the record: there is a bug in your code.

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

This appends a new line to your buffer; and then writes the whole buffer. But: the lines stay in your buffer!

So, maybe in this case, the "easy" answer is: clear the buffer after you wrote its content! Like: linea.delete(0, linea.length()). And btw: use StringBuilder; not StringBuffer. You could simply create a new builder for each line (instead of using/clearing the same builder all the time).

Most likely you get your exception because your StringBuffer keeps growing and growing; until you run out of memory.

Final note: stepping back is still the thing to do here. If I am not mistaken, the file you intend to create will have 38*38*38*38*38*38 lines, that makes up 3.010.936.384, so roughly 3 billion entries. Assume that each line contains 10, 15 bytes. So you end up with a file around 30 GB or so. But why? This file will contain a simple permutation of those values. And with a bit of math ... alone the line number could be used to compute the string that would be find in that line! Because you can map any value between 1 and 3.010.936.384 to the corresponding "permutation".

So, longer story short: whatever program is working with that 30 GB file - it doesn't need to. You know how many permutations exist; and you can easily compute (aka predict) the permutations. Any program that needs those permutations can do that! There is no point in writing 30 GB of data to the file system if you can compute the data so easily!

Thus, in essence: forget about writing this stuff to a file. You don't have you. That just costs you IO time writing and reading in later on. And you know, "IO" is still the most expensive thing to do.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • I would argue that writing a stream-based solution is not "trying threads." Parallel streams may be _implemented_ using threads, but from the programmer's point of view, it's a different abstraction. – Solomon Slow Sep 08 '16 at 13:12