Solved

Can't stop while loop calling unsychronized counter method.

Posted on 2000-05-18
3
235 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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
copyEndy  challenge 15 58
Starting to learn JAVA, 7 48
@SBGen Method 3 25
ArrayIndexOutOfBoundException 9 39
For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…

746 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now