Running java stream doesn't work

I have a simple exercise I am trying to do involving threads.

(a) Create a SumAction class that implements Runnable. The class contains 3 instance variables - start, end and sum. start and end are initialized by the constructor. the amount is set to 0.

(b) The run () method must have a for loop that must find the sum of all values ​​from start to finish. There must be a getSum () method to return the sum value.

(c) Basically create 2 instances of this Runnable class which takes 1 and 10 as parameters, the other takes 10 and 20.

(d) Pass these instances to two thread constructors to create threads t1 and t2.

(e) When the streams are finished, call getSum to get the sum value from both streams to find the total sum.

I'm sure I'm doing it right, but I'm still getting the sum of 0 back.

Here is my class

public class SumAction implements Runnable {

private int start, end, sum;

public SumAction(int start, int end) {
    this.start = start;
    this.end = end;
    sum = 0;
}

@Override
public void run()
{

    for (int i = start+1; i < end; i++)
    {
      sum += i;  
    }

}

public int getSum() {
    return sum;
}
}

      

Here are the main

    SumAction run1 = new SumAction(1, 10);

    SumAction run2 = new SumAction(10, 20);

    Thread t1= new Thread(run1);

    Thread t2= new Thread(run2);


    t1.start();

    t2.start();


    System.out.println("Sum 1 : " + run1.getSum());

    System.out.println("Sum 2 : " + run2.getSum());

      

+3


source to share


1 answer


You are not waiting for threads to finish. Your main thread can call getSum before other threads are running or before they start. It is also possible that the updated values ​​may not be visible on the main thread, even if the stream ends before println.

Call the threads to wait until they run out, add this after starting the threads and before printlns:

t1.join();
t2.join();

      

This ensures that the main thread waits until the other threads run out before trying to print the sums, and also takes care of the visibility issue.



In many cases, when a stream read from a field written by another thread is problematic (an implementation-dependent error, or just confusing and intractable), if adequate precautions (synchronization, changing a field, etc.) are not taken. But in this code, if you call join, then no additional synchronization is required for the main thread to make sure the last getSum value, because there is an applicable before-before rule. Quoting from the Oracle tutorial :

When a thread finishes and returns Thread.join on another thread, then all statements executed by the completed thread have a before relationship to all statements following a successful connection. The effects of code on a thread are now visible to the thread that made the connection.

The join method throws an InterruptedException, which is a checked exception, if a thread enters a wait or wait state after the interrupt flag is set. For a simple example program where you don't actually interrupt anything, you can add it to the throws clause of the main method.

+8


source







All Articles