Solved

Can't stop while loop calling unsychronized counter method.

Posted on 2000-05-18
3
241 Views
Last Modified: 2013-11-23

D:\course\threading>java Strange1
unsynchronized Start
synchronized Start
281382614 unsynchronized iterations.
7041533 synchronized iterations.
synchronized Stop
849434797 unsynchronized iterations.
7041533 synchronized iterations.

This behavior was discovered while experimenting with Synchronization and and the impact on Real Time.

Two threads are started running a counter.  One counts with an unsynchronized method.  The other counts with a synchronized method.  

After 10 seconds, a static variable is updated to stop the while loops that are doing the counting.  Note that the unsynchronized counter did not stop.

The two counts are output and, sure enough, the unsynchronized counter had many more cycles than the synchronized counter.

After waiting another 10 seconds, the counters are output again.  The synchronized count is still the same, confirming that it really did stop.  The unsynchronized count, is greatly increased, confirming that it really did not stop.  

I tried using an instance variable to stop the loop with the same results.  Why does the loop around the unsynchronized method call not notice that the static variable is now failing the while condition?

So I added some more code to the unsynchronized method and it behaved properly.

D:\course\Exercises>java Strange
unsynchronized Start
synchronized Start
527394 unsynchronized iterations.
5791502 synchronized iterations.
unsynchronized Stop
synchronized Stop
527395 unsynchronized iterations.
5791503 synchronized iterations.

Why the difference in behavior?

Thank you,
Harold Meder.
                                                         
--------------------------------------
import java.io.*;
public class Strange1 implements Runnable
{
   
   private int count = 0;
   private boolean sync = false;
   private static boolean cont = true;
   
   public Strange1()
   {
   }
   
   public Strange1(boolean _sync)
   {sync = _sync;
   }
   
   public void run() {
      count = 0;
      if(sync == true){
          System.out.println("synchronized Start");
          while (cont == true) {scount();}
          System.out.println("synchronized Stop");
      }
      else {
          System.out.println("unsynchronized Start");
          while (cont == true) {count();}
          System.out.println("unsynchronized Stop");
      }

   }

   private void count()
   {count++;
   }
   
   private synchronized void scount()
   {count++;
   }
   
   public static void main(String[] args) throws InterruptedException
   {
     Strange1 sync = new Strange1();
     Strange1 ssync = new Strange1(true);

    {
      Thread thread = new Thread(sync);
        thread.setPriority(Thread.MIN_PRIORITY);
      Thread sthread = new Thread(ssync);
        sthread.setPriority(Thread.MIN_PRIORITY);
      thread.start();
      sthread.start();
    }
      Thread.sleep(10000);
      cont = false;
    System.out.println(sync.count + " unsynchronized iterations.");
    System.out.println(ssync.count + " synchronized iterations.");
      Thread.sleep(10000);
    System.out.println(sync.count + " unsynchronized iterations.");
    System.out.println(ssync.count + " synchronized iterations.");
   }
}
----------------------------------------
import java.io.*;
public class Strange implements Runnable
{
   
   private int count = 0;
   private boolean sync = false;
   private static boolean cont = true;
   
   public Strange()
   {
   }
   
   public Strange(boolean _sync)
   {sync = _sync;
   }
   
   public void run() {
      String temp;
      count = 0;
      if(sync == true){
          System.out.println("synchronized Start");
          while (cont == true) {scount();}
          System.out.println("synchronized Stop");
      }
      else {
          System.out.println("unsynchronized Start");
          while (cont == true) {temp = " " + cont;count();}
          System.out.println("unsynchronized Stop");
      }

   }

   private void count()
   {count++;
   }
   
   private synchronized void scount()
   {count++;
   }
   
   public static void main(String[] args) throws InterruptedException
   {
     Strange sync = new Strange();
     Strange ssync = new Strange(true);

    {
      Thread thread = new Thread(sync);
        thread.setPriority(Thread.MIN_PRIORITY);
      Thread sthread = new Thread(ssync);
        sthread.setPriority(Thread.MIN_PRIORITY);
      thread.start();
      sthread.start();
    }
      Thread.sleep(10000);
      cont = false;
    System.out.println(sync.count + " unsynchronized iterations.");
    System.out.println(ssync.count + " synchronized iterations.");
      Thread.sleep(10000);
    System.out.println(sync.count + " unsynchronized iterations.");
    System.out.println(ssync.count + " synchronized iterations.");
   }
}

                                                                               

0
Comment
Question by:hwmeder
  • 2
3 Comments
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 200 total points
ID: 2821216
Well, I'm not entirely sure why -- I'm still trying to wade through the heavily formal language of the JVM spec -- but I am pleased to tell you two things about your problem.

First, it appears to be fixed in jdk1.3. Both versions of your class execute as expected.

Second, I was able to duplicate the problem on jdk1.2 and was able to correct it by the 'volatile' modifier to the cont boolean. My guess at this point is that the 1.2 JVM tries to optimize access to the variable by loading the value once on loop entry and using the loaded value for the duration of the loop. Strange1's additional code would not allow the JVM to perform this optimization because it accessed the value of cont within the loop thereby forcing a load operation. Notice that it isn't just _any_ additional code that will cause this. The cont variable must be accessed to induce this behavior.

In any event, try adding volatile to the declaration of cont. This should correct the problem without requiring you to upgrade to the latest jdk.

BTW, I compiled the class files using jikes -- not the javac compiler. And I tested the same class files on the JVMs from jdk1.2 and jdk1.3. I think this eliminates the javac compiler as the culprit.

Best regards,
Jim Cakalic
0
 

Author Comment

by:hwmeder
ID: 2822275
Adding the volatile modifier to the cont boolean resolved the problem for me.  I am using javac and jvm from jdk 1.2.2 in a DOS environment on Windows 95.

I guess this suggests that there is a defect in the JVM.

   Thank you,
      Harold Meder.
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2824362
Sacrilege!! Who woulda thunk it possible?
;-)
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Maven Project: Hibernate Dependencies Conflict 10 50
Opening PDF on button click and fill new document 2 54
ejb entity bean example 2 36
Coding for the first time 9 68
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question