Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code requiring "synchronized" works OK without it

This is a program from Herbert Schildt's Java Fundamentals to demonstrate synchronization.The method sumArray(int[]) is synchronized, and that is a requirement for the program to work correctly. However, when I removed the synchronized keyword, unexpectedly, the program showed almost the same output, and still gave correct results. This is the program.

class SumArray {
        private int sum;

        int sumArray(int[] nums) {
            sum = 0; // Reset sum.
            for(int i = 0; i < nums.length; i++) {
                sum += nums[i];
                System.out.println("Running total for " + Thread.currentThread().getName() + " is " + sum);
            }
            return sum;
        }
    }

    class SumThread implements Runnable {
        static SumArray sa = new SumArray();
        Thread thrd;
        int[] a;
        int answer;

        public SumThread(String name, int[] nums) {
            thrd = new Thread(this, name);
            a = nums;
            thrd.start();

        }

        @Override public void run() {
            System.out.println(thrd.getName() + " starting.");
            answer = sa.sumArray(a);
            System.out.println("Sum for " + thrd.getName() + " is " + answer);
            System.out.println(thrd.getName() + " terminating.");
        }

    }

    public class SyncExample {

        public static void main(String[] args) {
            int[] a = new int[] {1, 2, 3, 4, 5, 6};

            SumThread mt1 = new SumThread("Thread #1", a);
            SumThread mt2 = new SumThread("Thread #2", a);

            try {
                mt1.thrd.join();
                mt2.thrd.join();
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

Output.

Thread #1 starting.
Running total for Thread #1 is 1
Running total for Thread #1 is 3
Running total for Thread #1 is 6
Running total for Thread #1 is 10
Running total for Thread #1 is 15
Running total for Thread #1 is 21
Sum for Thread #1 is 21
Thread #1 terminating.
Thread #2 starting.
Running total for Thread #2 is 1
Running total for Thread #2 is 3
Running total for Thread #2 is 6
Running total for Thread #2 is 10
Running total for Thread #2 is 15
Running total for Thread #2 is 21
Sum for Thread #2 is 21
Thread #2 terminating.

Is there something wrong with my computer, or are threads supposed to be this strange?

like image 971
JavaNewbie_M107 Avatar asked Jan 12 '23 23:01

JavaNewbie_M107


1 Answers

You problem is that you have a very small array int[] a = new int[] {1, 2, 3, 4, 5, 6};.

Thread 1 finishes before even thread 2 starts.

If you try to run with array of 10000 or more elements you might see the difference.

I've run your code with 10000 elements:

Thread #1 starting.

Thread #2 starting.

Running total for Thread #1 is 1

Running total for Thread #2 is 1

Running total for Thread #1 is 3

Running total for Thread #2 is 5

Running total for Thread #2 is 11

Running total for Thread #2 is 15

Running total for Thread #1 is 8

..........

So even if your machine shows threads executing sequentially - there is no guarantee that it will this way on every machine and on every program launch.

Also, this way one more mistake is found:

EDIT

You've declared sum as a field which should be in fact a local variable. You can see in my output how this effects calculation (sum from one thread is modified by another and so on.)

like image 131
Tala Avatar answered Jan 22 '23 09:01

Tala