Search in sources :

Example 21 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project gocd by gocd.

the class ConcurrentHashMapV8 method internalComputeIfAbsent.

/** Implementation for computeIfAbsent */
private final Object internalComputeIfAbsent(K k, Fun<? super K, ?> mf) {
    int h = spread(k.hashCode());
    Object val = null;
    int count = 0;
    for (AtomicReferenceArray<Node> tab = table; ; ) {
        Node f;
        int i, fh;
        Object fk, fv;
        if (tab == null)
            tab = initTable();
        else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
            Node node = new Node(fh = h | LOCKED, k, null, null);
            if (casTabAt(tab, i, null, node)) {
                count = 1;
                try {
                    if ((val = mf.apply(k)) != null)
                        node.val = val;
                } finally {
                    if (val == null)
                        setTabAt(tab, i, null);
                    if (!node.casHash(fh, h)) {
                        node.hash = h;
                        synchronized (node) {
                            node.notifyAll();
                        }
                        ;
                    }
                }
            }
            if (count != 0)
                break;
        } else if ((fh = f.hash) == MOVED) {
            if ((fk = f.key) instanceof TreeBin) {
                TreeBin t = (TreeBin) fk;
                boolean added = false;
                t.acquire(0);
                try {
                    if (tabAt(tab, i) == f) {
                        count = 1;
                        TreeNode p = t.getTreeNode(h, k, t.root);
                        if (p != null)
                            val = p.val;
                        else if ((val = mf.apply(k)) != null) {
                            added = true;
                            count = 2;
                            t.putTreeNode(h, k, val);
                        }
                    }
                } finally {
                    t.release(0);
                }
                if (count != 0) {
                    if (!added)
                        return val;
                    break;
                }
            } else
                tab = (AtomicReferenceArray<Node>) fk;
        } else if ((fh & HASH_BITS) == h && (fv = f.val) != null && ((fk = f.key) == k || k.equals(fk)))
            return fv;
        else {
            Node g = f.next;
            if (g != null) {
                for (Node e = g; ; ) {
                    Object ek, ev;
                    if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && ((ek = e.key) == k || k.equals(ek)))
                        return ev;
                    if ((e = e.next) == null) {
                        checkForResize();
                        break;
                    }
                }
            }
            if (((fh = f.hash) & LOCKED) != 0) {
                checkForResize();
                f.tryAwaitLock(tab, i);
            } else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) {
                boolean added = false;
                try {
                    if (tabAt(tab, i) == f) {
                        count = 1;
                        for (Node e = f; ; ++count) {
                            Object ek, ev;
                            if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && ((ek = e.key) == k || k.equals(ek))) {
                                val = ev;
                                break;
                            }
                            Node last = e;
                            if ((e = e.next) == null) {
                                if ((val = mf.apply(k)) != null) {
                                    added = true;
                                    last.next = new Node(h, k, val, null);
                                    if (count >= TREE_THRESHOLD)
                                        replaceWithTreeBin(tab, i, k);
                                }
                                break;
                            }
                        }
                    }
                } finally {
                    if (!f.casHash(fh | LOCKED, fh)) {
                        f.hash = fh;
                        synchronized (f) {
                            f.notifyAll();
                        }
                        ;
                    }
                }
                if (count != 0) {
                    if (!added)
                        return val;
                    if (tab.length() <= 64)
                        count = 2;
                    break;
                }
            }
        }
    }
    if (val != null) {
        counter.add(1L);
        if (count > 1)
            checkForResize();
    }
    return val;
}
Also used : AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) RubyObject(org.jruby.RubyObject) IRubyObject(org.jruby.runtime.builtin.IRubyObject)

Example 22 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project guava by google.

the class CacheLoadingTest method ignoreTestExpandDuringRefresh.

// Test ignored because it is extremely flaky in CI builds
public void ignoreTestExpandDuringRefresh() throws InterruptedException, ExecutionException {
    final AtomicInteger callCount = new AtomicInteger();
    // tells the computing thread when to start computing
    final CountDownLatch computeSignal = new CountDownLatch(1);
    // tells the main thread when computation is pending
    final CountDownLatch secondSignal = new CountDownLatch(1);
    // tells the main thread when the second get has started
    final CountDownLatch thirdSignal = new CountDownLatch(1);
    // tells the main thread when the third get has started
    final CountDownLatch fourthSignal = new CountDownLatch(1);
    // tells the test when all gets have returned
    final CountDownLatch doneSignal = new CountDownLatch(3);
    final String suffix = "Suffix";
    CacheLoader<String, String> computeFunction = new CacheLoader<String, String>() {

        @Override
        public String load(String key) throws InterruptedException {
            callCount.incrementAndGet();
            secondSignal.countDown();
            computeSignal.await();
            return key + suffix;
        }
    };
    final AtomicReferenceArray<String> result = new AtomicReferenceArray<String>(2);
    final LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(computeFunction);
    final String key = "bar";
    cache.asMap().put(key, key);
    // start computing thread
    new Thread() {

        @Override
        public void run() {
            cache.refresh(key);
            doneSignal.countDown();
        }
    }.start();
    // wait for computation to start
    secondSignal.await();
    checkNothingLogged();
    // start waiting thread
    new Thread() {

        @Override
        public void run() {
            thirdSignal.countDown();
            result.set(0, cache.getUnchecked(key));
            doneSignal.countDown();
        }
    }.start();
    // give the second get a chance to run; it is okay for this to be racy
    // as the end result should be the same either way
    thirdSignal.await();
    Thread.yield();
    // Expand!
    CacheTesting.forceExpandSegment(cache, key);
    // start another waiting thread
    new Thread() {

        @Override
        public void run() {
            fourthSignal.countDown();
            result.set(1, cache.getUnchecked(key));
            doneSignal.countDown();
        }
    }.start();
    // give the third get a chance to run; it is okay for this to be racy
    // as the end result should be the same either way
    fourthSignal.await();
    Thread.yield();
    // let computation finish
    computeSignal.countDown();
    doneSignal.await();
    assertTrue(callCount.get() == 1);
    assertEquals(key, result.get(0));
    assertEquals(key, result.get(1));
    assertEquals(key + suffix, cache.getUnchecked(key));
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) CountDownLatch(java.util.concurrent.CountDownLatch) Thread.currentThread(java.lang.Thread.currentThread)

Example 23 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project guava by google.

the class CacheLoadingTest method testExpandDuringLoading.

public void testExpandDuringLoading() throws InterruptedException {
    final int count = 3;
    final AtomicInteger callCount = new AtomicInteger();
    // tells the computing thread when to start computing
    final CountDownLatch computeSignal = new CountDownLatch(1);
    // tells the main thread when computation is pending
    final CountDownLatch secondSignal = new CountDownLatch(1);
    // tells the main thread when the second get has started
    final CountDownLatch thirdSignal = new CountDownLatch(1);
    // tells the main thread when the third get has started
    final CountDownLatch fourthSignal = new CountDownLatch(1);
    // tells the test when all gets have returned
    final CountDownLatch doneSignal = new CountDownLatch(count);
    CacheLoader<String, String> computeFunction = new CacheLoader<String, String>() {

        @Override
        public String load(String key) throws InterruptedException {
            callCount.incrementAndGet();
            secondSignal.countDown();
            computeSignal.await();
            return key + "foo";
        }
    };
    final LoadingCache<String, String> cache = CacheBuilder.newBuilder().weakKeys().build(computeFunction);
    final AtomicReferenceArray<String> result = new AtomicReferenceArray<String>(count);
    final String key = "bar";
    // start computing thread
    new Thread() {

        @Override
        public void run() {
            result.set(0, cache.getUnchecked(key));
            doneSignal.countDown();
        }
    }.start();
    // wait for computation to start
    secondSignal.await();
    // start waiting thread
    new Thread() {

        @Override
        public void run() {
            thirdSignal.countDown();
            result.set(1, cache.getUnchecked(key));
            doneSignal.countDown();
        }
    }.start();
    // give the second get a chance to run; it is okay for this to be racy
    // as the end result should be the same either way
    thirdSignal.await();
    Thread.yield();
    // Expand!
    CacheTesting.forceExpandSegment(cache, key);
    // start another waiting thread
    new Thread() {

        @Override
        public void run() {
            fourthSignal.countDown();
            result.set(2, cache.getUnchecked(key));
            doneSignal.countDown();
        }
    }.start();
    // give the third get a chance to run; it is okay for this to be racy
    // as the end result should be the same either way
    fourthSignal.await();
    Thread.yield();
    // let computation finish
    computeSignal.countDown();
    doneSignal.await();
    assertTrue(callCount.get() == 1);
    assertEquals("barfoo", result.get(0));
    assertEquals("barfoo", result.get(1));
    assertEquals("barfoo", result.get(2));
    assertEquals("barfoo", cache.getUnchecked(key));
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) CountDownLatch(java.util.concurrent.CountDownLatch) Thread.currentThread(java.lang.Thread.currentThread)

Example 24 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project guava by hceylan.

the class CacheLoadingTest method doConcurrentGet.

/**
   * Test-helper method that performs {@code nThreads} concurrent calls to {@code cache.get(key)}
   * or {@code cache.getUnchecked(key)}, and returns a List containing each of the results. The
   * result for any given call to {@code cache.get} or {@code cache.getUnchecked} is the value
   * returned, or the exception thrown.
   *
   * <p>As we iterate from {@code 0} to {@code nThreads}, threads with an even index will call
   * {@code getUnchecked}, and threads with an odd index will call {@code get}. If the cache throws
   * exceptions, this difference may be visible in the returned List.
   */
private static <K> List<Object> doConcurrentGet(final LoadingCache<K, ?> cache, final K key, int nThreads, final CountDownLatch gettersStartedSignal) throws InterruptedException {
    final AtomicReferenceArray<Object> result = new AtomicReferenceArray<Object>(nThreads);
    final CountDownLatch gettersComplete = new CountDownLatch(nThreads);
    for (int i = 0; i < nThreads; i++) {
        final int index = i;
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                gettersStartedSignal.countDown();
                Object value = null;
                try {
                    int mod = index % 3;
                    if (mod == 0) {
                        value = cache.get(key);
                    } else if (mod == 1) {
                        value = cache.getUnchecked(key);
                    } else {
                        cache.refresh(key);
                        value = cache.get(key);
                    }
                    result.set(index, value);
                } catch (Throwable t) {
                    result.set(index, t);
                }
                gettersComplete.countDown();
            }
        });
        thread.start();
        // (in startSignal.await()), and the others waiting for that thread's result.
        while (thread.isAlive() && thread.getState() != Thread.State.WAITING) {
            Thread.yield();
        }
    }
    gettersStartedSignal.countDown();
    gettersComplete.await();
    List<Object> resultList = Lists.newArrayListWithExpectedSize(nThreads);
    for (int i = 0; i < nThreads; i++) {
        resultList.add(result.get(i));
    }
    return resultList;
}
Also used : AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 25 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project aerospike-client-java by aerospike.

the class Command method getSequenceNode.

private final Node getSequenceNode(Cluster cluster, Partition partition) {
    // Must copy hashmap reference for copy on write semantics to work.
    HashMap<String, AtomicReferenceArray<Node>[]> map = cluster.partitionMap;
    AtomicReferenceArray<Node>[] replicaArray = map.get(partition.namespace);
    if (replicaArray != null) {
        for (int i = 0; i < replicaArray.length; i++) {
            int index = Math.abs(sequence % replicaArray.length);
            Node node = replicaArray[index].get(partition.partitionId);
            if (node != null && node.isActive()) {
                return node;
            }
            sequence++;
        }
    }
    return cluster.getRandomNode();
}
Also used : Node(com.aerospike.client.cluster.Node) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray)

Aggregations

AtomicReferenceArray (java.util.concurrent.atomic.AtomicReferenceArray)31 CountDownLatch (java.util.concurrent.CountDownLatch)13 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)9 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)6 RubyObject (org.jruby.RubyObject)6 IRubyObject (org.jruby.runtime.builtin.IRubyObject)6 Config (com.hazelcast.config.Config)4 HazelcastInstance (com.hazelcast.core.HazelcastInstance)4 Random (java.util.Random)4 Test (org.junit.Test)4 Thread.currentThread (java.lang.Thread.currentThread)3 ExecutorService (java.util.concurrent.ExecutorService)3 JoinConfig (com.hazelcast.config.JoinConfig)2 MulticastConfig (com.hazelcast.config.MulticastConfig)2 NetworkConfig (com.hazelcast.config.NetworkConfig)2 TcpIpConfig (com.hazelcast.config.TcpIpConfig)2 IMap (com.hazelcast.core.IMap)2 TestHazelcastInstanceFactory (com.hazelcast.test.TestHazelcastInstanceFactory)2 QuickTest (com.hazelcast.test.annotation.QuickTest)2 ArrayList (java.util.ArrayList)2