Hi, I'm trying to get the threads synchronized, but the output I get is still wrong:

Expected sum: 20000000
Actual sum: 10000000

Do I use synchronized wrong, or do I put it in a wrong place?

class TestThread extends Thread
   {
   public void run()
      {
      for (int i = 1; i <= SampleRace.N1; i++)
         {
         //System.out.println(SampleRace.sum);
         SampleRace.sum = SampleRace.calcsum(SampleRace.sum);
         }
      } // run
   } // class TestThread



public class SampleRace
   {
   public static final int N1 = 1000;
   public static final int N2 = 10000;
   public static int sum = 0;

   public synchronized static int calcsum(int sum)
      {
      int tmp;

      tmp = sum;
      for (int i = 0; i < N2; i++)
          tmp = tmp + 1;
      //System.out.println(sum);
      return(tmp);
      }

   public static void main(String[] args) throws InterruptedException
      {

      // start the tasks
      TestThread t1 = new TestThread();
      t1.start();

      TestThread t2 = new TestThread();
      t2.start();

      // wait for the tasks to finish
      t1.join();
      t2.join();

      // print results
      System.out.println("Expected sum: " + 2 * N1 * N2);
      System.out.println("Actual sum:   " + sum);
      } // main
   } // class SampleRace

Thanks,

Waldis

The output is unpredictable.
Depending on the exact order in which the threads run you will get a different result.

This is caused by your threads each holding on to their own local sum variable and overwriting the global one.

A correct version of the program would be like this:

class TestThread extends Thread  {
   public void run() {
      for (int i = 1; i <= SampleRace.N1; i++)  {
           SampleRace.calcsum();
      }
   }
}

public class SampleRace {
   public static final int N1 = 1000;
   public static final int N2 = 10000;
   public static int sum = 0;

   public synchronized static void calcsum()  {
      for (int i = 0; i < N2; i++)
          sum++;
      System.out.println(sum);
   }

   public static void main(String[] args) throws InterruptedException  {
      TestThread t1 = new TestThread();
      t1.start();

      TestThread t2 = new TestThread();
      t2.start();

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

      System.out.println("Expected sum: " + 2 * N1 * N2);
      System.out.println("Actual sum:   " + sum);
   }
}

Also cleaned up and corrected your formatting to conform to the official language standard.

I appreciate your input! I really feel that I should've started all this programming adventure some 25 years ago when I was in my teenage years, but time has gone by and I have to settle with what I got...

I have added a counting semaphore class (I have to implement it myself without using Java built in semaphores), and changed some things around. When I run it, it displays numbers, and the result is correct, but it takes considerable time (half a minute or so) to count. I guess I have done something wrong again...

class CountingSemaphore {
    protected int count;

    public CountingSemaphore() {
        count=0;
    }

    public synchronized void take() throws InterruptedException {
        while (count==0)
            wait();
        count--;
    }

    public synchronized void add() {
        count++;
        notify();
    }

    public synchronized int get() {
        return count;
    }
}

class TestThread extends Thread {
    public void run() {
        for (int i = 1; i <= SampleRace.N1; i++) {
            SampleRace.calcsum();
        }
    }
}

public class SampleRace {
    public static final int N1 = 1000;
    public static final int N2 = 10000;
    public static CountingSemaphore sum = new CountingSemaphore();

    public static void calcsum() {
        for (int i = 0; i < N2; i++)
            sum.add();
        System.out.println(sum.get());
    }

    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        t1.start();

        TestThread t2 = new TestThread();
        t2.start();

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

        System.out.println("Expected sum: " + 2 * N1 * N2);
        System.out.println("Actual sum:   " + sum.get());
    }
}

Thanks again,

Waldis

This article has been dead for over six months. Start a new discussion instead.