From 7ba474dbbf0c6c5bc66a406ac79613695421cafe Mon Sep 17 00:00:00 2001 From: clay_shooter <> Date: Fri, 8 Dec 2006 13:03:55 +0000 Subject: [PATCH] SF1603631: concurrent modification of ROT (adding or removing thread tables) causes VM crash. The simple fix is to sychronize all accessors to the ROT. Performance impact has not been analyzed --- jacob/unittest/com/jacob/com/ROT3Test.java | 40 ++++++++++++---------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/jacob/unittest/com/jacob/com/ROT3Test.java b/jacob/unittest/com/jacob/com/ROT3Test.java index 8cbd68f..e12b818 100644 --- a/jacob/unittest/com/jacob/com/ROT3Test.java +++ b/jacob/unittest/com/jacob/com/ROT3Test.java @@ -34,7 +34,7 @@ public static void main(String args[]) throws Exception class ROT3TestThread extends Thread { - private java.util.List ThreadObjects; + private java.util.List variansCreatedInThisThread; private int initialRunSize = 0; /** @@ -59,34 +59,35 @@ public void run() // something that keeps object references around // so the gc can't collect them // we need to create these in the thread so they end up in the right ROT table - ThreadObjects = new java.util.ArrayList(initialRunSize); + variansCreatedInThisThread = new java.util.ArrayList(initialRunSize); for (int i = 0; i < initialRunSize; i++) { // create the object Variant aNewVariant = new Variant(getName() + "_" + i); // create a hard reference to it - ThreadObjects.add(aNewVariant); + variansCreatedInThisThread.add(aNewVariant); } - while (ThreadObjects.size() > 1) + while (variansCreatedInThisThread.size() > 1) { String message = ""; - message = getName()+" Workingset=" +ThreadObjects.size() - +" ROT: "+ROT.getThreadObjects(true).hashCode(); - message += " before mods and gc "+ROT.getThreadObjects(true).size()+")"; - // if there is an odd number of objects greater than 2 - if (ThreadObjects.size() > 10) + message = getName()+" Workingset=" +variansCreatedInThisThread.size() + +" ROT threadObject hashCode: "+ROT.getThreadObjects(true).hashCode(); + message += " size before mods and gc "+ROT.getThreadObjects(true).size()+")"; + // If there are more than 10 objects in our cache then add 1/4 of that again + if (variansCreatedInThisThread.size() > 10) { - message+= " ++ "; - for ( int i = 0 ; i < ThreadObjects.size()/4 ; i++){ + message+= " (adding) "; + // add an additional 1/4 of our current number + for ( int i = 0 ; i < variansCreatedInThisThread.size()/4 ; i++){ // add a new object - Variant aNewVariant = new Variant(getName() + "_*" + ThreadObjects.size()); - ThreadObjects.add(aNewVariant); + Variant aNewVariant = new Variant(getName() + "_*" + variansCreatedInThisThread.size()); + variansCreatedInThisThread.add(aNewVariant); } } - // now iterate across all the objects in our list - message += " -- "; - for (int i = ThreadObjects.size(); i > 0; i--) + // now iterate across 1/2 the objects in our list + message += " (removing) "; + for (int i = variansCreatedInThisThread.size(); i > 0; i--) { // removing every other one? if (i % 2 == 0) @@ -95,9 +96,9 @@ public void run() if (!ROT.USE_AUTOMATIC_GARBAGE_COLLECTION){ // uses deprecated API to set up a special situation // because this is an ROT test - ROT.removeObject((JacobObject)ThreadObjects.get(i-1)); + ROT.removeObject((JacobObject)variansCreatedInThisThread.get(i-1)); } - ThreadObjects.remove(i-1); + variansCreatedInThisThread.remove(i-1); } } @@ -109,7 +110,8 @@ public void run() } System.gc(); try { - Thread.sleep(2000); + // vain attempt at letting the gc run + Thread.sleep(200); } catch (InterruptedException ie){ }