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