public void Run() { int count = AtLeast(Rnd, 10000); for (int i = 0; i < count; i++) { int j = Rnd.Next(KeyCount); switch (Rnd.Next(5)) { case 0: Map.Put(Keys.Get(j), Convert.ToInt32(j)); break; case 1: int?v = Map.Get(Keys.Get(j)); if (v != null) { Assert.AreEqual(j, (int)v); } break; case 2: Map.Remove(Keys.Get(j)); break; case 3: // renew key, the old one will be GCed at some time: Keys.Set(j, new object()); break; case 4: // check iterator still working for (IEnumerator <object> it = Map.Keys.GetEnumerator(); it.MoveNext();) { Assert.IsNotNull(it.Current); } break; default: Assert.Fail("Should not get here."); break; } } }
public virtual void TestConcurrentHashMap() { // don't make threadCount and keyCount random, otherwise easily OOMs or fails otherwise: const int threadCount = 8, keyCount = 1024; ExecutorService exec = Executors.newFixedThreadPool(threadCount, new NamedThreadFactory("testConcurrentHashMap")); WeakIdentityMap <object, int?> map = WeakIdentityMap <object, int?> .NewConcurrentHashMap(Random().NextBoolean()); // we keep strong references to the keys, // so WeakIdentityMap will not forget about them: AtomicReferenceArray <object> keys = new AtomicReferenceArray <object>(keyCount); for (int j = 0; j < keyCount; j++) { keys.Set(j, new object()); } try { for (int t = 0; t < threadCount; t++) { Random rnd = new Random(Random().Next()); exec.execute(new RunnableAnonymousInnerClassHelper(this, keyCount, map, keys, rnd)); } } finally { exec.shutdown(); while (!exec.awaitTermination(1000L, TimeUnit.MILLISECONDS)) { ; } } // clear strong refs for (int j = 0; j < keyCount; j++) { keys.Set(j, null); } // check that GC does not cause problems in reap() method: int size = map.Size(); for (int i = 0; size > 0 && i < 10; i++) { try { System.runFinalization(); System.gc(); int newSize = map.Size(); Assert.IsTrue(size >= newSize, "previousSize(" + size + ")>=newSize(" + newSize + ")"); size = newSize; Thread.Sleep(new TimeSpan(100L)); int c = 0; for (IEnumerator <object> it = map.Keys.GetEnumerator(); it.MoveNext();) { Assert.IsNotNull(it.Current); c++; } newSize = map.Size(); Assert.IsTrue(size >= c, "previousSize(" + size + ")>=iteratorSize(" + c + ")"); Assert.IsTrue(c >= newSize, "iteratorSize(" + c + ")>=newSize(" + newSize + ")"); size = newSize; } catch (ThreadInterruptedException ie) { } } }
public virtual void TestConcurrentHashMap() { // don't make threadCount and keyCount random, otherwise easily OOMs or fails otherwise: const int threadCount = 8, keyCount = 1024; ExecutorService exec = Executors.newFixedThreadPool(threadCount, new NamedThreadFactory("testConcurrentHashMap")); WeakIdentityMap<object, int?> map = WeakIdentityMap<object, int?>.NewConcurrentHashMap(Random().NextBoolean()); // we keep strong references to the keys, // so WeakIdentityMap will not forget about them: AtomicReferenceArray<object> keys = new AtomicReferenceArray<object>(keyCount); for (int j = 0; j < keyCount; j++) { keys.Set(j, new object()); } try { for (int t = 0; t < threadCount; t++) { Random rnd = new Random(Random().Next()); exec.execute(new RunnableAnonymousInnerClassHelper(this, keyCount, map, keys, rnd)); } } finally { exec.shutdown(); while (!exec.awaitTermination(1000L, TimeUnit.MILLISECONDS)) ; } // clear strong refs for (int j = 0; j < keyCount; j++) { keys.Set(j, null); } // check that GC does not cause problems in reap() method: int size = map.Size(); for (int i = 0; size > 0 && i < 10; i++) { try { System.runFinalization(); System.gc(); int newSize = map.Size(); Assert.IsTrue(size >= newSize, "previousSize(" + size + ")>=newSize(" + newSize + ")"); size = newSize; Thread.Sleep(new TimeSpan(100L)); int c = 0; for (IEnumerator<object> it = map.Keys.GetEnumerator(); it.MoveNext(); ) { Assert.IsNotNull(it.Current); c++; } newSize = map.Size(); Assert.IsTrue(size >= c, "previousSize(" + size + ")>=iteratorSize(" + c + ")"); Assert.IsTrue(c >= newSize, "iteratorSize(" + c + ")>=newSize(" + newSize + ")"); size = newSize; } catch (ThreadInterruptedException ie) { } } }