mardi 5 mai 2020

new Thread(runnable).start() doesnt work properly but run() does

I'm trying to learn more about Threads and how they work. I'd like to use a PrintStream and write random double values to a file until my Predicate stops it.

This is my Main class:

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.function.Predicate;

public class Main {
public static void main(String[] args) {
    File file = new File("C:\\Users\\Internet\\Desktop\\test123.txt");

    try (OutputStream out = new FileOutputStream(file); PrintStream print = new PrintStream(out)) {
        if (!file.exists())
            file.createNewFile();
        Predicate<Integer> pred = new CountPredicate(5);
        Runnable runnable = new RandomWriteRunner(pred, print);
        new Thread(runnable).start();
        //PrintStream p = r.getPrintStream();
        //runnable.run();

    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

This is my class CountPredicate which implements Predicate and uses test() to determine whether the stop criteria is reached.

import java.util.function.Predicate;

public class CountPredicate implements Predicate<Integer> {

private int max;

public CountPredicate(int max) {
    this.max = max;
}

@Override
public boolean test(Integer current) {
    return current >= max;
}
}

And this is my RandomWriteRunner class which implements Runnable and uses the constructor to give the run() method its values to work with.

import java.io.PrintStream;
import java.util.Random;
import java.util.function.Predicate;

public class RandomWriteRunner implements Runnable {

private Random random;
private Predicate<Integer> stopCriterion;
private int generatedSoFar;
private PrintStream printStream;

public RandomWriteRunner(Predicate<Integer> stopCriterion, PrintStream printStream) {
    random = new Random();
    this.stopCriterion = stopCriterion;
    generatedSoFar = 0;
    this.printStream = printStream;
}

@Override
public void run() {
    while (!stopCriterion.test(generatedSoFar)) {
        printStream.println(random.nextDouble());
        generatedSoFar++;
        System.out.println(generatedSoFar);
    }
}

public PrintStream getPrintStream() {
    return this.printStream;
}
}

Since i cant access the printStream variable, because its private, i use a Getter to play with it in my Main class.

I tried writing this:

RandomWriteRunner r = new RandomWriteRunner(pred, print);
Runnable runnable = r;
new Thread(runnable).start();
PrintStream p = r.getPrintStream();
p.print('a');

Normally i would open my txt file and it would be empty but this time it said 'a' and a random double number. Why does it do that? And are those 6 random double values still in my PrintStream? When i use new Thread(runnable).run(); it works but i heard thats because the run() method is called from my current Thread and thats not what i want. Also when i use the code as it is and add the runnable.run() written as a comment in my Main class my console shows the values from 1 to 6 instead of 1 to 5. The reason why im so confused is that the run method is obviously called since my console shows me the System.out.println(generatedSoFar); but it doesnt print the random double numbers to the file. Am i missing something obvious? Thanks for all answers.




Aucun commentaire:

Enregistrer un commentaire