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)
                {
                }
            }
        }