2

Question : I have to create 5 threads where each thread has to perform the addition operation.

  • Thread1 - Add 1 to 10
  • Thread2 - Add 1 to 50
  • Thread3 - Add 5 to 15
  • Thread4 - Add 10 to 20
  • Thread5 - Add 15 to 20

What is the best way to accomplish this? Also, I need 1 sec time delay between each addition operation. I have written this code: My output is wrong and changing every time. I know problem is with synchronized but not able solve.

class adding implements Runnable{
    int a,b; 
    public adding(int a, int b){
        this.a = a;
        this.b = b;
    }
    public void run() {
        add(a,b);
    }
    public void add(int a, int b){
        int sum=0;
        synchronized (this) {
            for(int i=a;i<=b;i++){
                sum = sum+ a;
            }
            System.out.println("Sum of "+a+" to "+ b+" numbers = "+sum);    
        }
    }
}

public class addnumbersusing5threads {
    public static void main(String[] args) {
        Thread t1 = new Thread(new adding(1,10));
        Thread t2 = new Thread(new adding(1,50));
        Thread t3 = new Thread(new adding(5,15));
        Thread t4 = new Thread(new adding(10,20));
        Thread t5 = new Thread(new adding(15,20));
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

Output:

Sum of 1 to 10 numbers = 10  
Sum of 1 to 50 numbers = 50 
Sum of 5 to 15 numbers = 55 
Sum of 10 to 20 numbers = 110 
Sum of 15 to 20 numbers = 90 
Antxon
  • 1,855
  • 15
  • 21
UserJS
  • 131
  • 1
  • 1
  • 7
  • You need to synchronize around both reads and writes of a and b if you want to use monitors as mutex guards. (Also please make your class names start with a CapitalLetter!) – BadZen Apr 14 '15 at 04:53
  • Do you want the results to appear in exactly this order (1 to 10, then 1 to 50, etc.), or the order is irrelevant as long as there is a one second delay between operations? – FreeNickname Apr 14 '15 at 04:53
  • Order doesn't matter but what if it matters? Can you explain both the approaches? – UserJS Apr 14 '15 at 04:55
  • I think for maintaining the order, thread joins would be used. – UserJS Apr 14 '15 at 05:07
  • @BadZen `a` and `b` are _local variables_. They are not visible to more than one thread, and so they need no synchronization. – Solomon Slow Apr 14 '15 at 13:42
  • `synchronized (this)` has absolutely no effect in this program: A `synchronized` block has no effect until more than one thread attempts to synchronize on the same object, but that never happens in this program: Each of your threads has its own instance of the `adding` class to work on, and they never interact with one another. – Solomon Slow Apr 14 '15 at 13:50

3 Answers3

11

here is the problem:

sum = sum + a;

it should be sum += i;

BTW, you don't need any synchronization here

if you want delay between additions - use Thread.sleep(1000L);

Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
  • 1
    You need synchronization to implement a 1s delay between calculations, I believe. – FreeNickname Apr 14 '15 at 04:57
  • That, or you take the print statements out of the `Thread` implementation and have the caller wait for each thread to complete and then print the results in the desired order/with the desired timing. – aroth Apr 14 '15 at 04:59
  • @FreeNickname The simplest way for any thread to wait for one second is to call `Thread.sleep(1000)`. That's not "synchronization" because it does not affect any thread other than the one that calls it. – Solomon Slow Apr 14 '15 at 13:45
  • @jameslarge, It depends on the task interpretation. I guess, that you assume, that there should be a 1 second delay between every `sum = sum+ a;` operation. In this case I would agree with you. However, I believe, that the task asks to add a pause between calls to the `add()` function (it is more probable, since the task seems to be devoted to thread synchronization), and every call to the `add()` function is performed on a separate thread. So, we have to synchronize them. – FreeNickname Apr 14 '15 at 18:58
3

As per Lashane, there is no need to synchronize here - there is no contention on sum as each thread will have its own variable. (And if you do need to synchronize, don't synchronize on this as the object reference has scope outside of the class and could e.g. be subject to deadlock - instead, synchronize on a private field object, e.g. private final Object lock = new Object();)

 public void add(int a, int b){
    int sum=0;
    for(int i=a;i<=b;i++){
        sum = sum + i;
        Thread.sleep(1000);
    }
    System.out.println("Sum of "+a+" to "+ b+" numbers = "+sum);
}

Also, after starting threads, you will need to join them back into the main thread.

...
t4.start();
t5.start();
// Join
t1.join();
t2.join();
...
Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
1

Add Thread.sleep(1000L) to your add method

   public void add(int a, int b) throws InterruptedException {
        int sum=0;
        synchronized (this) {
            for(int i=a;i<=b;i++){
                sum += i;
                Thread.sleep(1000L); // Add this line for one second delay on each addition
            }
            System.out.println("Sum of "+a+" to "+ b+" numbers = "+sum);

        }
    }
sriman reddy
  • 763
  • 8
  • 22