One revision -- the prev. code only ensures synchronicity, not 
once-through and synchronized. This is correct:

  private void initialize() {
    //System.out.println("geodesic init " + testInit  + " started");
    if (testInit.x++ > 0) {
      while (testInit.y == 0) {
Bob Hanson wrote:

>OK, I've identified the problem:
>
>1) In Geodesics we see:
>
> Geodesic3D(Graphics3D g3d) {
>    this.g3d = g3d;
>    if (vertexCounts == null)
>      initialize();
>  }
>
>
>  private synchronized void initialize() {
>    if (vertexCounts != null) {
>      return;
>    }
>    vertexCounts = new short[maxLevel];
>   .....
> }
>
>
>Fine, this APPEARS to say, "If some other thread has not STARTED to 
>initialize the geodesic normals system, go ahead and initialize." That's 
>important, because only the first thread should initialize. Note that 
>this is not "the first thread from this web page loading" but "the first 
>thread from any page from this server (or, perhaps, from this server 
>using this Jar file, I suspect) since the Jmol applet has first been 
>used in this browser session."
>
>2) It turns out there are two problems with this:
>
>Problem 1: It is NOT "Wait here until some other thread has FINISHED 
>initializing the geodesci normals system." Miguel is saying, "Oh 
>[EMAIL PROTECTED]" right now. Because while one thread has STARTED -- but not 
>FINISHED -- initializing the normals system, another thread has bypassed 
>initialization and is fast into creating an isosurface that needs that 
>system.
>
>Problem 2: You (apparently) cannot use synchronization within a 
>constructor. At least in Firefox (the only browser I tested this on) I 
>changed the above to this:
>
>  Geodesic3D(Graphics3D g3d) {
>    this.g3d = g3d;
>    String msg = "Geodesecs "+ System.currentTimeMillis();
>    System.out.println(msg+" 0");
>    initialize();
>    System.out.println(msg+" 1");
>  }
>
>  private synchronized void initialize() {
>    System.out.println("geodesic init");
>    if (vertexCounts != null) {
>      System.out.println("geodesic init skipped");     
>      return;
>    }
>    System.out.println("geodesic init continuing");
>    vertexCounts = new short[maxLevel];
>   ...
>    for(int i=0;i++<1000000;){String s="";}  // just to slow it down
>    System.out.println("geodesic init 1");
>  }
>
>Now, you might expect to see the threads wait for the synchronization, 
>right? But NOOOO! I get for a page displaying eight orbitals [added 
>comments in brackets]:
>
>Geodesecs 1149943353546 0
>Geodesecs 1149943353546 0
>Geodesecs 1149943353546 0
>Geodesecs 1149943353546 0
>Geodesecs 1149943353546 0
>Geodesecs 1149943353546 0
>
>[that's six of them]
>
>geodesic init
>geodesic init
>geodesic init
>geodesic init
>Geodesecs 1149943353546 0
>geodesic init
>geodesic init
>
>[how can this be -- they are synchronized, no? Ah, but they are 
>CONSTRUCTORS!]
>
>geodesic init continuing
>geodesic init continuing
>geodesic init continuing
>geodesic init continuing
>
>[you're kidding, right? ALL continuing? What happened to the sync?]
>
>geodesic init
>geodesic init continuing
>geodesic init continuing
>
>[#$&[EMAIL PROTECTED]
>
>geodesic init 1
>
>[at this point 7 contructors have started, 7 have started into 
>initialize() in full, 5 are CONTINUING, one has completed initialize(); 
>one is unaccounted for, and none have finished construction of Geodesics.]
>
>Could not instantiate wrappedApplet classorg.jmol.applet.Jmol
>java.lang.NullPointerException
>    at org.jmol.g3d.Geodesic3D.getVertex(Geodesic3D.java:406)
>    at org.jmol.g3d.Geodesic3D.quadruple(Geodesic3D.java:296)
>    at org.jmol.g3d.Geodesic3D.initialize(Geodesic3D.java:216)
>    at org.jmol.g3d.Geodesic3D.<init>(Geodesic3D.java:180)
>    at org.jmol.g3d.Graphics3D.<init>(Graphics3D.java:104)
>    at org.jmol.viewer.Viewer.<init>(Viewer.java:121)
>    at org.jmol.viewer.Viewer.allocateViewer(Viewer.java:143)
>    at org.jmol.api.JmolViewer.allocateViewer(JmolViewer.java:51)
>    at org.jmol.applet.Jmol.initWindows(Jmol.java:182)
>    at org.jmol.applet.Jmol.init(Jmol.java:145)
>    at 
>org.jmol.appletwrapper.WrappedAppletLoader.run(WrappedAppletLoader.java:51)
>
>[There it is!!! No surprise here, I guess.]
>
>geodesic init 1
>geodesic init skipped
>geodesic init 1
>geodesic init 1
>
>[3 more have done the FULL initialization; one did skip]
>
>Geodesecs 1149943353546 1
>Geodesecs 1149943353546 1
>Geodesecs 1149943353671 0
>Geodesecs 1149943353546 1
>Geodesecs 1149943353546 1
>
>[ok, the first 4 threads have completed construction of Geodesics; #8 is 
>finally getting going]
>
>Could not instantiate wrappedApplet classorg.jmol.applet.Jmol
>java.lang.NullPointerException
>    at org.jmol.g3d.Geodesic3D.getVertex(Geodesic3D.java:406)
>    at org.jmol.g3d.Geodesic3D.quadruple(Geodesic3D.java:295)
>    at org.jmol.g3d.Geodesic3D.initialize(Geodesic3D.java:216)
>    at org.jmol.g3d.Geodesic3D.<init>(Geodesic3D.java:180)
>    at org.jmol.g3d.Graphics3D.<init>(Graphics3D.java:104)
>    at org.jmol.viewer.Viewer.<init>(Viewer.java:121)
>    at org.jmol.viewer.Viewer.allocateViewer(Viewer.java:143)
>    at org.jmol.api.JmolViewer.allocateViewer(JmolViewer.java:51)
>    at org.jmol.applet.Jmol.initWindows(Jmol.java:182)
>    at org.jmol.applet.Jmol.init(Jmol.java:145)
>    at 
>org.jmol.appletwrapper.WrappedAppletLoader.run(WrappedAppletLoader.java:51)
>
>[argh!]
>
>geodesic init
>geodesic init skipped
>Geodesecs 1149943353671 1
>
>[#8 skips all initialization]
>
>Geodesecs 1149943353546 1
>
>[six completions; two errors; page shows orbitals 1,2,3,4,5, and 7, but 
>not 6 or 8]
>
>
>THAT's the problem. I leave it to Miguel to tell us the elegant 
>solution. Mine is a classic no-synchronize entry/exit flag system using 
>a static boolean array:
>
>  Geodesic3D(Graphics3D g3d) {
>    this.g3d = g3d;
>    String msg = "Geodesecs "+ System.currentTimeMillis();
>    System.out.println(msg+" 0");
>    initialize();
>    System.out.println(msg+" 1");
>  }
>
>  static Point3i testInit = new Point3i();
>  private void initialize() {
>    System.out.println("geodesic init " + testInit  + " started");
>    if (testInit.x++ > 0 && testInit.y == 0) {
>      while (testInit.y == 0) {
>        try{
>          Thread.sleep(10);
>        } catch(Exception e) {
>          System.out.println("geodesic error "+e);
>        }
>        System.out.println("geodesic init "+ testInit + " waiting");
>      }
>      System.out.println("geodesic init skipped");     
>      return;
>    }
>    System.out.println("geodesic init " + testInit + " continuing");
>...
>    System.out.println("geodesic init " + testInit + " completed");
>    ++testInit.y;
>  }
>
>Note that this takes advantage of the fact that Point3i is an object 
>that allows storage of two values and that, though static, allows for 
>the modification of these values. I'm just using testInit.x and 
>testInit.y. I now get:
>
>Geodesecs 1149949067812 0
>geodesic init (0, 0, 0) started
>geodesic init (1, 0, 0) continuing
>Geodesecs 1149949067843 0
>geodesic init (1, 0, 0) started
>Geodesecs 1149949067843 0
>geodesic init (2, 0, 0) started
>Geodesecs 1149949067843 0
>geodesic init (3, 0, 0) started
>Geodesecs 1149949067843 0
>geodesic init (4, 0, 0) started
>Geodesecs 1149949067843 0
>geodesic init (5, 0, 0) started
>geodesic init (6, 0, 0) waiting
>geodesic init (6, 0, 0) waiting
>geodesic init (6, 0, 0) waiting
>geodesic init (6, 0, 0) waiting
>Geodesecs 1149949067843 0
>geodesic init (6, 0, 0) started
>geodesic init (7, 0, 0) waiting
>Geodesecs 1149949067843 0
>geodesic init (7, 0, 0) started
>geodesic init (8, 0, 0) completed
>Geodesecs 1149949067812 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>geodesic init (8, 1, 0) waiting
>geodesic init skipped
>Geodesecs 1149949067843 1
>
>
>That's it! I see 8 orbitals now, and only one full initialization.
>No synchronization.
>Comments?
>
>Bob
>
>
>
>_______________________________________________
>Jmol-developers mailing list
>[email protected]
>https://lists.sourceforge.net/lists/listinfo/jmol-developers
>  
>



_______________________________________________
Jmol-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jmol-developers

Reply via email to