This discussion is archived
1 2 Previous Next 15 Replies Latest reply: Jan 23, 2013 1:34 AM by 985922 RSS

Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)

985922 Newbie
Currently Being Moderated
Hello,

the API-documentation of Java 5 states that 'Vector' is synchronized (in fact: older versions state this as well). But using the Java 5 JDK final-release 1.5.0_22, I get the following Console-Output for the Testclass below (presumably, because the copy-constructor of Vector is not synchronized and thus the whole class is not synchronized - please correct me if I'm wrong). Note: The iterator only operates on the copy, the static vector is not accessed by iterators, only by its member-operations. The interrupt of the loop happens obviously because there is some concurreny error in the copy-constructor causing 'null'-values being inserted into the copied vector.

Console output:

Main-Thread started.
null-element found.
Read-Thread terminated.
Main-Thread terminated.
Write-Thread terminated.

When executing the following Testclass:
import java.util.Iterator;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;

public class VectorTest extends Thread {
  private static CountDownLatch terminateMainThread = new CountDownLatch(1);
  private static final Vector<String> v = new Vector<String>();
  private boolean writeMode;
  private static boolean endless;
  public VectorTest(boolean writeMode) {
          this.writeMode = writeMode;
          endless = true;
  }
  public void run() {
          if (writeMode) {
                  while (endless) {
                          for (int i=1; i<= 10000; i++) {
                                  v.add("DummyString");
                          }
                          while (v.size()>1000) {
                                  v.remove(v.firstElement());
                          }
                  }
                  System.out.println("Write-Thread terminated.");
          } else {
                  while (endless) {
                          Vector<String> copy = new Vector<String>(v);
                          Iterator<String> it = copy.iterator();
                          while (it.hasNext()) {
                                  if (it.next()==null) {
                                          System.out.println("null-element found.");
                                          endless = false;
                                          terminateMainThread.countDown();
                                          break;
                                  }
                          }
                  }
                  System.out.println("Read-Thread terminated.");
          }
  }
  public static void main(String[] args) throws InterruptedException {
          System.out.println("Main-Thread started.");
          VectorTest w = new VectorTest(true);
          VectorTest r = new VectorTest(false);
          w.start();
          r.start();
          terminateMainThread.await();
          System.out.println("Main-Thread terminated.");
  }
}
I cannot reproduce this behavior using newer Java-versions (for them, only "Main-Thread started." is put out and the application runs endless), that is this presumable bug is presumably fixed since some Java 6 release.
  • 1. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    EJP Guru
    Currently Being Moderated
    Of course it's synchronized. But iterating over Vectors has never been synchronized. It is up to the application do do that. Your code is incorrect, or rather it has undefined behaviour.
  • 2. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    966867 Newbie
    Currently Being Moderated
    I think your code should throw a ConcurrentModificationException.

    Take a look at SynchronousQueue, it was created for producer-consumer scenario, maybe it is helpful in your case.

    http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/SynchronousQueue.html

    Regards
    Andrej
  • 3. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    985922 Newbie
    Currently Being Moderated
    The usage of Iterator happens on a function-local copy, that is it could not be the cause for the strange behavior. If you still believe that the Iterator-usage is the issue here, try the following instead (the iterator-loop is replaced by a contains()-call). The behavior is the same.
    import java.util.Vector;
    import java.util.concurrent.CountDownLatch;
    
    
    public class VectorTest extends Thread {
      private static CountDownLatch terminateMainThread = new CountDownLatch(1);
      private static final Vector<String> v = new Vector<String>();
      private boolean writeMode;
      private static boolean endless;
      public VectorTest(boolean writeMode) {       
           this.writeMode = writeMode;
           endless = true;
      }
      public void run() {
           if (writeMode) {
                while (endless) {
                     for (int i=1; i<= 10000; i++) {
                          v.add("DummyString");
                     }
                     while (v.size()>1000) {
                          v.remove(v.firstElement());
                     }
                }
                System.out.println("Write-Thread terminated.");
           } else {
                while (endless) {
                     Vector<String> copy = new Vector<String>(v);
                     if (copy.contains(null)) {
                          System.out.println("null-element found.");
                          endless = false;                           
                          terminateMainThread.countDown();
                          break;
                     }
                }
                System.out.println("Read-Thread terminated.");
           }
      }
      public static void main(String[] args) throws InterruptedException {
           System.out.println("Main-Thread started.");
           VectorTest w = new VectorTest(true);
           VectorTest r = new VectorTest(false);
           w.start();
           r.start();
           terminateMainThread.await();
           System.out.println("Main-Thread terminated.");
      }
    }
  • 4. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    985922 Newbie
    Currently Being Moderated
    @zarr, thank you for the hint. But the question is not to fix this code.

    My question is: Does this code show that Vector is not synchronized in Java 5? The goal of the code is to proof this statement. If someone has still the opinion that Vector is synchronized in Java 5: What is the reason for the behavior-deviation between Java 5 and Java 6?
  • 5. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    966867 Newbie
    Currently Being Moderated
    I have Java 1.7.0_05 installed, and I can’t reproduce your issue.

    My console output is always: “Main-Thread started.”
    How long have you executed your program to get described issue? I executed this example for few minutes.

    Regards
    Andrej
  • 6. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    985922 Newbie
    Currently Being Moderated
    @zarr, yes (as I said) I also cannot reproduce the issue with later Java versions, that is: I can reproduce the problem with Java 1.5.0_22, but not with Java 6 and also not with Java 7. Using 1.5.0_22, the described issue is shown immediately after program start (less than one second of execution time).
  • 7. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    ++sja Explorer
    Currently Being Moderated
    This was indeed a bug in earlier versions. If you have src.zip of JDK 5 and a later version, compare the implementation of the constructor in java/util/Vector.java. It's not hard to see how it can fail.
  • 8. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    985922 Newbie
    Currently Being Moderated
    @sia, thank you. Following your hint, I compared the copy-constructor of Vector.java between 1.5.0_22 (year of the file: 2009) and 1.6.0 (the first Java 6 version, year of the file: 2006). The bug was already fixed in the first Java 6 version, but presumably not because of the concurrency issue. The comment in the function refers to bug number 6260652 which has (as far as I understand) nothing to do with concurrency. That is the bug was presumably fixed "by accident". And the bug still were published three year long in the JDK updates for Java-5.
  • 9. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    gimbal2 Guru
    Currently Being Moderated
    Lesson learned: don't run on old end of life and unsupported tech.
  • 10. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    985922 Newbie
    Currently Being Moderated
    @gimbal2: Yes, but this is difficult if you have customers who need support for legacy systems running old java applications. My lesson learned is in particular: Don't use Java, respectively take difficult maintenance into account, if you plan to implement and support a system running longer than three years. Java evolves far more quickly than C/C++.
  • 11. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    EJP Guru
    Currently Being Moderated
    So the conclusion here is that the 'copy constructor' wasn't properly synchronized. Not the entire class.
  • 12. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    985922 Newbie
    Currently Being Moderated
    @EJP, my conclusion is:

    The term "synchronized" is somehow overloaded in Java: Non-constructor methods could be "synchronized" (usage of the keyword "synchronized" in the member-function definition), which means that the monitor associated with the class object is aquired. This term relates to the state of the object itself. Because of this, there is no Java mechanism to synchronize constructors in this sense (it is assumed that this is not needed, the state of the object should only be accessed concurrently after complete object creation). On the other hand, I did not found a clear definition in the Java specification of the term "synchronized" in relation to a class (That is: What is the exact meaning of the API-docu statement "Vectors are synchronized"?). I assume the intended meaning is: A class is "synchronized" if all its (non-constructor-) member-functions are synchronized. The third term-usage of "synchronized" is related to the statement level ("synchronized statement"). I think there is a forth meaning of "synchronized", generalized from Java, I would define this similar to this: A sequence A1...An of actions is "synchronized", if the state space on which the actions operate, is not changed by other actions during the time interval start(A1) ... end(An).

    Due to this: The issue of this thread was, that the copy constructor did not synchronized ('synchronized' in the forth sense) its own accesses to its operand with concurrent accesses properly. I think strictly this was not even a bug, because I found no statement in the API or Java specification which forces such a synchronization. Maybe there is a hole in the Java respectively API specification. It would be fine if it would be more clear in the future if some Java concurrent behavior is wrong or correct.
  • 13. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    Kayaman Guru
    Currently Being Moderated
    982919 wrote:
    The term "synchronized" is somehow overloaded in Java
    It shouldn't be really.
    That is: What is the exact meaning of the API-docu statement "Vectors are synchronized"?
    It should really say "The Vector class is thread-safe".
  • 14. Re: Vector in Java 5 is presumably *not* synchronized (due to its copy-ctor)
    EJP Guru
    Currently Being Moderated
    , which means that the monitor associated with the class object is aquired.
    No, of the instance object, unless the method is static.
    I assume the intended meaning is: A class is "synchronized" if all its (non-constructor-) member-functions are synchronized.
    Me too, and in that sense Vector is indeed synchronized, in all versions, so your title is incorrect. That's what I was clarifying.
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points