0

the attached programcode produces the following output most of the time:

6.0
8.0
10.0
12.0

java.lang.RuntimeException: dimensions not matching
    at hausaufgaben.linearAlgebra1.VectorRn.add(VectorRn.java:41)
    at hausaufgaben.linearAlgebra1.VectorRn.main(VectorRn.java:19)

3.0
6.0
9.0
12.0

but at the second execution it produced following output

6.0
8.0
10.0
12.0

java.lang.RuntimeException: dimensions not matching
3.0
6.0
9.0
12.0

    at hausaufgaben.linearAlgebra1.VectorRn.add(VectorRn.java:41)
    at hausaufgaben.linearAlgebra1.VectorRn.main(VectorRn.java:19)

does this mean that in simple programms with consoleoutput there are already race-conditions that behave deterministically in 99.99% of the time ?

or is the catch statement executed in a seperate thread ?

or is the console.output cued up ina weird way ?

I'm confused at how something like this could have occured, even if it is rare.

package hausaufgaben.linearAlgebra1;

public class VectorRn {
/**
 * values that are the components
 */
private double[] values;

/**
 * @param args
 */
public static void main(String[] args) {
    VectorRn a = new VectorRn(1,2,3,4);
    VectorRn b = new VectorRn(5,6,7,8);
    VectorRn c = new VectorRn(1,2);
    double d = 3;
    System.out.println(a.add(b).toString());
    try {
        System.out.println(a.add(c).toString());
    }catch(Exception e) {
        e.getMessage();
        e.printStackTrace();
    }
    System.out.println("\n"+a.mult(d).toString());
}    

/**
 * @param values copies the values passed to the constructor
 */
public VectorRn(double... values) {
    this.values = new double[values.length];
    System.arraycopy(values, 0, this.values, 0, values.length);
}

/**
 * @param v2 the vector added to a clone of this object
 * @return the sum of this Vector and v2
 */
public VectorRn add(VectorRn v2) {
    if(this.values.length != v2.values.length)
        throw new RuntimeException("dimensions not matching");
    VectorRn modifiedClone = new VectorRn(this.values);
    for(int i = 0; i < modifiedClone.values.length; i++){
        modifiedClone.values[i] += v2.values[i];
    }
    return modifiedClone;
}


/**
 * @param d the scalar by which the clone of this object will be multiplied
 * @return the d'th multiple of this Vector
 */
public VectorRn mult(double d) {
    VectorRn modifiedClone = new VectorRn(this.values);
    for(int i = 0; i < this.values.length; i++) {
        modifiedClone.values[i] *= d;
    }
    return modifiedClone;
}

/**
 * @return a string that contains a list of the components of the vector separated by newline characters
 * @see java.lang.Object#toString()
 */
public String toString() {
    StringBuilder tmp = new StringBuilder();
    for(double d : values) {
        tmp.append(d);
        tmp.append("\n");
    }
    return tmp.toString();
}
}

2 Answers2

5

e.printStackTrace prints messages to stderr (System.err), whereas all other output goes to stdout (System.out). By default, both standard output streams are redirected onto the same target (your terminal). So your program is running deterministically, it's just outputting to two to channels.

This behavior is actually a good idea; a program can redirect the output but still present errors to the users. If you however don't want it, you can print errors to stdout with

e.printStackTrace(System.out)
phihag
  • 278,196
  • 72
  • 453
  • 469
  • 2
    +1. Note that this does, in fact, reflect concurrency: at some level in the terminal, the writing of standard output and the writing of standard error are happening in parallel. – ruakh Oct 12 '14 at 23:08
  • thanks for the answer, makes sense but I would never have guessed that the statments are printed non-atomic, as the stacktrace is divided into 2 parts here, on the other hand I have no clue what exactly happens when printing –  Oct 12 '14 at 23:11
1

There is only one thread so there can't be a race condition in your code. What you are seeing is the interleaving of System.out and System.err streams. See for example Cause runtime exceptions to be properly ordered with println in console output

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783