Code requiring "synchronized" works fine without it

This is a program from Herbert Schildt's Java Essentials to demonstrate synchronization. The sumArray(int[]) method is synchronized , and this is a prerequisite for the program to work properly. However, when I deleted the synchronized , unexpectedly, the program showed almost the same result and still gave the correct results. This 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 something wrong with my computer, or should the streams be so weird?

+4
source share
2 answers

Is something wrong with my computer, or should the streams be so weird?

No, your system is absolutely perfect. Yes. Streams should be so weird. Now there are many possible reasons for this output from your program:

  • The size of the array is very small. Thus, the operation is performed so quickly before the processor cycle can be transferred to another thread.
  • There sumArray no Thread.sleep() method in Thread.sleep() that can force the current thread to leave execution for a while and allow another thread to get a processor loop.
  • mt1.thrd.join(); runs before mt2.thrd . This makes all threads wait until mt1.thrd completes execution.

How to see unsynchronized behavior?

Make the following changes:

  int sumArray(int[] nums) { sum = 0; // Reset sum. for(int i = 0; i < nums.length; i++) { sum += nums[i]; try{ Thread.sleep(100);//Make the current thread to sleep for 100 ms }catch(Exception ex){ex.printStackTrace();} System.out.println("Running total for " + Thread.currentThread().getName() + " is " + sum); } return sum; } 

Then another change:

 int[] a = new int[400];//increase the size of array for (int i = 0 ; i < a.length ; i++) a[i] = i; 

And then,

  SumThread mt2 = new SumThread("Thread #2", a); try{ Thread.sleep(1000);//make to main thread to sleep before mt1.thrd.join() could be called. }catch(Exception ex){ex.printStackTrace();} try { mt1.thrd.join(); .... 
+3
source

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

Thread 1 ends before the start of flow.

If you try to run an array of 10,000 or more elements, you can see the difference.

I ran your code with 10,000 elements:

Launching topic number 1.

Launching topic number 2.

The total amount for Thread # 1 is 1

The total amount for Thread # 2 is 1

The total amount for Thread # 1 is 3

The total amount for topic number 2 is 5

The total amount for topic number 2 is 11

The total amount for topic number 2 is 15

The total amount for Thread # 1 is 8

..........

Thus, even if your computer shows threads running sequentially, there is no guarantee that this will be the case on every computer and every time the program starts.

In addition, another error was found in this way:

EDIT

You declared the sum as a field, which should be actually a local variable. You can see in my output how these effects are calculated (the sum from one stream changes by another, etc.).

+6
source

Source: https://habr.com/ru/post/1490022/


All Articles