Example usage for java.util.concurrent.atomic AtomicLong incrementAndGet

List of usage examples for java.util.concurrent.atomic AtomicLong incrementAndGet

Introduction

In this page you can find the example usage for java.util.concurrent.atomic AtomicLong incrementAndGet.

Prototype

public final long incrementAndGet() 

Source Link

Document

Atomically increments the current value, with memory effects as specified by VarHandle#getAndAdd .

Usage

From source file:Test.java

public static void main(String[] args) {
    final AtomicLong orderIdGenerator = new AtomicLong(0);
    final List<Item> orders = Collections.synchronizedList(new ArrayList<Item>());

    for (int i = 0; i < 10; i++) {
        Thread orderCreationThread = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    long orderId = orderIdGenerator.incrementAndGet();
                    Item order = new Item(Thread.currentThread().getName(), orderId);
                    orders.add(order);//from ww w . ja  v  a2 s  . co m
                }
            }
        });
        orderCreationThread.setName("Order Creation Thread " + i);
        orderCreationThread.start();
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    Set<Long> orderIds = new HashSet<Long>();
    for (Item order : orders) {
        orderIds.add(order.getID());
        System.out.println("Order id:" + order.getID());
    }
}

From source file:org.apache.eagle.alert.engine.e2e.SampleClient1.java

public static void main(String[] args) {
    long base = System.currentTimeMillis();
    AtomicLong msgCount = new AtomicLong();

    Config config = ConfigFactory.load();
    try (KafkaProducer<String, String> proceduer = createProceduer(config)) {
        while (true) {
            int hostIndex = 6;
            for (int i = 0; i < hostIndex; i++) {
                base = send_metric(base, proceduer, PERFMON_CPU_STREAM, i);
                msgCount.incrementAndGet();
                base = send_metric(base, proceduer, PERFMON_MEM_STREAM, i);
                msgCount.incrementAndGet();
            }/*  www .  j a  v  a2s. co  m*/

            if ((msgCount.get() % 600) == 0) {
                System.out.println("send 600 CPU/MEM metric!");
            }

            Utils.sleep(3000);
        }
    }
}

From source file:io.covert.dns.collection.ResolverThread.java

public static void main(String[] args) throws Exception {

    ConcurrentLinkedQueue<DnsRequest> inQueue = new ConcurrentLinkedQueue<DnsRequest>();
    AtomicLong inQueueSize = new AtomicLong(0);
    ConcurrentLinkedQueue<Pair<Record, Message>> outQueue = new ConcurrentLinkedQueue<Pair<Record, Message>>();
    String[] nameservers = new String[] { "8.8.8.8" };

    inQueue.add(new DnsRequest("www6.google.com.", Type.AAAA, DClass.IN));
    inQueue.add(new DnsRequest("ipv6.google.com.", Type.AAAA, DClass.IN));
    inQueue.add(new DnsRequest("gmail.com.", Type.AAAA, DClass.IN));
    inQueueSize.incrementAndGet();
    inQueueSize.incrementAndGet();/*  ww w.j  a  v a 2 s .  co m*/
    inQueueSize.incrementAndGet();

    ResolverThread res = new ResolverThread(inQueue, inQueueSize, outQueue, nameservers, 5);
    res.start();
    res.stopRunning();
    res.join();

    Pair<Record, Message> result = outQueue.remove();
    System.out.println(result);

    result = outQueue.remove();
    System.out.println(result);

    result = outQueue.remove();
    System.out.println(result);
}

From source file:com.cloudera.oryx.app.traffic.TrafficUtil.java

public static void main(String[] args) throws Exception {
    if (args.length < 3) {
        System.err.println("usage: TrafficUtil [hosts] [requestIntervalMS] [threads] [... other args]");
        return;//from  w ww  . j  av a2s .  com
    }

    String[] hostStrings = COMMA.split(args[0]);
    Preconditions.checkArgument(hostStrings.length >= 1);
    int requestIntervalMS = Integer.parseInt(args[1]);
    Preconditions.checkArgument(requestIntervalMS >= 0);
    int numThreads = Integer.parseInt(args[2]);
    Preconditions.checkArgument(numThreads >= 1);

    String[] otherArgs = new String[args.length - 3];
    System.arraycopy(args, 3, otherArgs, 0, otherArgs.length);

    List<URI> hosts = Arrays.stream(hostStrings).map(URI::create).collect(Collectors.toList());

    int perClientRequestIntervalMS = numThreads * requestIntervalMS;

    Endpoints alsEndpoints = new Endpoints(ALSEndpoint.buildALSEndpoints());
    AtomicLong requestCount = new AtomicLong();
    AtomicLong serverErrorCount = new AtomicLong();
    AtomicLong clientErrorCount = new AtomicLong();
    AtomicLong exceptionCount = new AtomicLong();

    long start = System.currentTimeMillis();
    ExecUtils.doInParallel(numThreads, numThreads, true, i -> {
        RandomGenerator random = RandomManager.getRandom(Integer.toString(i).hashCode() ^ System.nanoTime());
        ExponentialDistribution msBetweenRequests;
        if (perClientRequestIntervalMS > 0) {
            msBetweenRequests = new ExponentialDistribution(random, perClientRequestIntervalMS);
        } else {
            msBetweenRequests = null;
        }

        ClientConfig clientConfig = new ClientConfig();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(numThreads);
        connectionManager.setDefaultMaxPerRoute(numThreads);
        clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
        clientConfig.connectorProvider(new ApacheConnectorProvider());
        Client client = ClientBuilder.newClient(clientConfig);

        try {
            while (true) {
                try {
                    WebTarget target = client.target("http://" + hosts.get(random.nextInt(hosts.size())));
                    Endpoint endpoint = alsEndpoints.chooseEndpoint(random);
                    Invocation invocation = endpoint.makeInvocation(target, otherArgs, random);

                    long startTime = System.currentTimeMillis();
                    Response response = invocation.invoke();
                    try {
                        response.readEntity(String.class);
                    } finally {
                        response.close();
                    }
                    long elapsedMS = System.currentTimeMillis() - startTime;

                    int statusCode = response.getStatusInfo().getStatusCode();
                    if (statusCode >= 400) {
                        if (statusCode >= 500) {
                            serverErrorCount.incrementAndGet();
                        } else {
                            clientErrorCount.incrementAndGet();
                        }
                    }

                    endpoint.recordTiming(elapsedMS);

                    if (requestCount.incrementAndGet() % 10000 == 0) {
                        long elapsed = System.currentTimeMillis() - start;
                        log.info("{}ms:\t{} requests\t({} client errors\t{} server errors\t{} exceptions)",
                                elapsed, requestCount.get(), clientErrorCount.get(), serverErrorCount.get(),
                                exceptionCount.get());
                        for (Endpoint e : alsEndpoints.getEndpoints()) {
                            log.info("{}", e);
                        }
                    }

                    if (msBetweenRequests != null) {
                        int desiredElapsedMS = (int) Math.round(msBetweenRequests.sample());
                        if (elapsedMS < desiredElapsedMS) {
                            Thread.sleep(desiredElapsedMS - elapsedMS);
                        }
                    }
                } catch (Exception e) {
                    exceptionCount.incrementAndGet();
                    log.warn("{}", e.getMessage());
                }
            }
        } finally {
            client.close();
        }
    });
}

From source file:org.apache.eagle.alert.engine.e2e.SampleClient2.java

private static void sendMetric(AtomicLong base1, AtomicLong base2, AtomicLong count,
        KafkaProducer<String, String> proceduer, int i) {
    {/*from   ww w. ja  v  a  2  s .  com*/
        Pair<Long, String> pair = createLogEntity(base1, i);
        ProducerRecord<String, String> logRecord = new ProducerRecord<>("eslogs", pair.getRight());
        proceduer.send(logRecord);
        count.incrementAndGet();
    }
    {
        Pair<Long, String> pair2 = createFailureEntity(base2, i);
        ProducerRecord<String, String> failureRecord = new ProducerRecord<>("bootfailures", pair2.getRight());
        proceduer.send(failureRecord);
        count.incrementAndGet();
    }
}

From source file:org.apache.hadoop.hbase.regionserver.handler.HLogSplitterHandler.java

/**
 * endTask() can fail and the only way to recover out of it is for the
 * {@link SplitLogManager} to timeout the task node.
 * @param slt/*from w  w  w .ja v  a2s. c o m*/
 * @param ctr
 */
public static void endTask(ZooKeeperWatcher zkw, SplitLogTask slt, AtomicLong ctr, String task,
        int taskZKVersion) {
    try {
        if (ZKUtil.setData(zkw, task, slt.toByteArray(), taskZKVersion)) {
            LOG.info("successfully transitioned task " + task + " to final state " + slt);
            ctr.incrementAndGet();
            return;
        }
        LOG.warn("failed to transistion task " + task + " to end state " + slt
                + " because of version mismatch ");
    } catch (KeeperException.BadVersionException bve) {
        LOG.warn("transisition task " + task + " to " + slt + " failed because of version mismatch", bve);
    } catch (KeeperException.NoNodeException e) {
        LOG.fatal("logic error - end task " + task + " " + slt + " failed because task doesn't exist", e);
    } catch (KeeperException e) {
        LOG.warn("failed to end task, " + task + " " + slt, e);
    }
    SplitLogCounters.tot_wkr_final_transition_failed.incrementAndGet();
}

From source file:com.alibaba.rocketmq.tools.command.message.PrintMessageByQueueCommand.java

private static void calculateByTag(final List<MessageExt> msgs, final Map<String, AtomicLong> tagCalmap,
        final boolean calByTag) {
    if (!calByTag)
        return;/*from  w  w w . ja va2s.c  o m*/

    for (MessageExt msg : msgs) {
        String tag = msg.getTags();
        if (StringUtils.isNotBlank(tag)) {
            AtomicLong count = tagCalmap.get(tag);
            if (count == null) {
                count = new AtomicLong();
                tagCalmap.put(tag, count);
            }
            count.incrementAndGet();
        }
    }
}

From source file:org.structr.core.graph.NodeServiceCommand.java

/**
 * Executes the given transaction until the stop condition evaluates to
 * <b>true</b>.//w  w w.  j ava  2s  . co m
 *
 * @param securityContext
 * @param commitCount the number of executions after which the transaction is committed
 * @param transaction the operation to execute
 * @param stopCondition
 * @throws FrameworkException
 */
public static void bulkTransaction(final SecurityContext securityContext, final long commitCount,
        final StructrTransaction transaction, final Predicate<Long> stopCondition) throws FrameworkException {

    final App app = StructrApp.getInstance(securityContext);
    final AtomicLong objectCount = new AtomicLong(0L);

    while (!stopCondition.evaluate(securityContext, objectCount.get())) {

        try (final Tx tx = app.tx()) {

            long loopCount = 0;

            while (loopCount++ < commitCount && !stopCondition.evaluate(securityContext, objectCount.get())) {

                transaction.execute();
                objectCount.incrementAndGet();
            }

            tx.success();
        }
    }
}

From source file:io.druid.client.cache.MemcachedCache.java

public static MemcachedCache create(final MemcachedCacheConfig config) {
    final ConcurrentMap<String, AtomicLong> counters = new ConcurrentHashMap<>();
    final ConcurrentMap<String, AtomicLong> meters = new ConcurrentHashMap<>();
    final AbstractMonitor monitor = new AbstractMonitor() {
        final AtomicReference<Map<String, Long>> priorValues = new AtomicReference<Map<String, Long>>(
                new HashMap<String, Long>());

        @Override/*from   ww w  .  j a  va 2 s. com*/
        public boolean doMonitor(ServiceEmitter emitter) {
            final Map<String, Long> priorValues = this.priorValues.get();
            final Map<String, Long> currentValues = getCurrentValues();
            final ServiceMetricEvent.Builder builder = ServiceMetricEvent.builder();
            for (Map.Entry<String, Long> entry : currentValues.entrySet()) {
                emitter.emit(builder.setDimension("memcached metric", entry.getKey())
                        .build("query/cache/memcached/total", entry.getValue()));
                final Long prior = priorValues.get(entry.getKey());
                if (prior != null) {
                    emitter.emit(builder.setDimension("memcached metric", entry.getKey())
                            .build("query/cache/memcached/delta", entry.getValue() - prior));
                }
            }

            if (!this.priorValues.compareAndSet(priorValues, currentValues)) {
                log.error("Prior value changed while I was reporting! updating anyways");
                this.priorValues.set(currentValues);
            }
            return true;
        }

        private Map<String, Long> getCurrentValues() {
            final ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder();
            for (Map.Entry<String, AtomicLong> entry : counters.entrySet()) {
                builder.put(entry.getKey(), entry.getValue().get());
            }
            for (Map.Entry<String, AtomicLong> entry : meters.entrySet()) {
                builder.put(entry.getKey(), entry.getValue().get());
            }
            return builder.build();
        }
    };
    try {
        LZ4Transcoder transcoder = new LZ4Transcoder(config.getMaxObjectSize());

        // always use compression
        transcoder.setCompressionThreshold(0);

        OperationQueueFactory opQueueFactory;
        long maxQueueBytes = config.getMaxOperationQueueSize();
        if (maxQueueBytes > 0) {
            opQueueFactory = new MemcachedOperationQueueFactory(maxQueueBytes);
        } else {
            opQueueFactory = new LinkedOperationQueueFactory();
        }

        final Predicate<String> interesting = new Predicate<String>() {
            // See net.spy.memcached.MemcachedConnection.registerMetrics()
            private final Set<String> interestingMetrics = ImmutableSet.of(
                    "[MEM] Reconnecting Nodes (ReconnectQueue)",
                    //"[MEM] Shutting Down Nodes (NodesToShutdown)", // Busted
                    "[MEM] Request Rate: All", "[MEM] Average Bytes written to OS per write",
                    "[MEM] Average Bytes read from OS per read",
                    "[MEM] Average Time on wire for operations (s)",
                    "[MEM] Response Rate: All (Failure + Success + Retry)", "[MEM] Response Rate: Retry",
                    "[MEM] Response Rate: Failure", "[MEM] Response Rate: Success");

            @Override
            public boolean apply(@Nullable String input) {
                return input != null && interestingMetrics.contains(input);
            }
        };

        final MetricCollector metricCollector = new MetricCollector() {
            @Override
            public void addCounter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                counters.putIfAbsent(name, new AtomicLong(0L));

                if (log.isDebugEnabled()) {
                    log.debug("Add Counter [%s]", name);
                }
            }

            @Override
            public void removeCounter(String name) {
                if (log.isDebugEnabled()) {
                    log.debug("Ignoring request to remove [%s]", name);
                }
            }

            @Override
            public void incrementCounter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0));
                    counter = counters.get(name);
                }
                counter.incrementAndGet();

                if (log.isDebugEnabled()) {
                    log.debug("Increment [%s]", name);
                }
            }

            @Override
            public void incrementCounter(String name, int amount) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0));
                    counter = counters.get(name);
                }
                counter.addAndGet(amount);

                if (log.isDebugEnabled()) {
                    log.debug("Increment [%s] %d", name, amount);
                }
            }

            @Override
            public void decrementCounter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0));
                    counter = counters.get(name);
                }
                counter.decrementAndGet();

                if (log.isDebugEnabled()) {
                    log.debug("Decrement [%s]", name);
                }
            }

            @Override
            public void decrementCounter(String name, int amount) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0L));
                    counter = counters.get(name);
                }
                counter.addAndGet(-amount);

                if (log.isDebugEnabled()) {
                    log.debug("Decrement [%s] %d", name, amount);
                }
            }

            @Override
            public void addMeter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                meters.putIfAbsent(name, new AtomicLong(0L));
                if (log.isDebugEnabled()) {
                    log.debug("Adding meter [%s]", name);
                }
            }

            @Override
            public void removeMeter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                if (log.isDebugEnabled()) {
                    log.debug("Ignoring request to remove meter [%s]", name);
                }
            }

            @Override
            public void markMeter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong meter = meters.get(name);
                if (meter == null) {
                    meters.putIfAbsent(name, new AtomicLong(0L));
                    meter = meters.get(name);
                }
                meter.incrementAndGet();

                if (log.isDebugEnabled()) {
                    log.debug("Increment counter [%s]", name);
                }
            }

            @Override
            public void addHistogram(String name) {
                log.debug("Ignoring add histogram [%s]", name);
            }

            @Override
            public void removeHistogram(String name) {
                log.debug("Ignoring remove histogram [%s]", name);
            }

            @Override
            public void updateHistogram(String name, int amount) {
                log.debug("Ignoring update histogram [%s]: %d", name, amount);
            }
        };

        final ConnectionFactory connectionFactory = new MemcachedCustomConnectionFactoryBuilder()
                // 1000 repetitions gives us good distribution with murmur3_128
                // (approx < 5% difference in counts across nodes, with 5 cache nodes)
                .setKetamaNodeRepetitions(1000).setHashAlg(MURMUR3_128)
                .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
                .setLocatorType(ConnectionFactoryBuilder.Locator.CONSISTENT).setDaemon(true)
                .setFailureMode(FailureMode.Cancel).setTranscoder(transcoder).setShouldOptimize(true)
                .setOpQueueMaxBlockTime(config.getTimeout()).setOpTimeout(config.getTimeout())
                .setReadBufferSize(config.getReadBufferSize()).setOpQueueFactory(opQueueFactory)
                .setMetricCollector(metricCollector).setEnableMetrics(MetricType.DEBUG) // Not as scary as it sounds
                .build();

        final List<InetSocketAddress> hosts = AddrUtil.getAddresses(config.getHosts());

        final Supplier<ResourceHolder<MemcachedClientIF>> clientSupplier;

        if (config.getNumConnections() > 1) {
            clientSupplier = new LoadBalancingPool<MemcachedClientIF>(config.getNumConnections(),
                    new Supplier<MemcachedClientIF>() {
                        @Override
                        public MemcachedClientIF get() {
                            try {
                                return new MemcachedClient(connectionFactory, hosts);
                            } catch (IOException e) {
                                log.error(e, "Unable to create memcached client");
                                throw Throwables.propagate(e);
                            }
                        }
                    });
        } else {
            clientSupplier = Suppliers.<ResourceHolder<MemcachedClientIF>>ofInstance(StupidResourceHolder
                    .<MemcachedClientIF>create(new MemcachedClient(connectionFactory, hosts)));
        }

        return new MemcachedCache(clientSupplier, config, monitor);
    } catch (IOException e) {
        throw Throwables.propagate(e);
    }
}

From source file:org.apache.druid.client.cache.MemcachedCache.java

public static MemcachedCache create(final MemcachedCacheConfig config) {
    final ConcurrentMap<String, AtomicLong> counters = new ConcurrentHashMap<>();
    final ConcurrentMap<String, AtomicLong> meters = new ConcurrentHashMap<>();
    final AbstractMonitor monitor = new AbstractMonitor() {
        final AtomicReference<Map<String, Long>> priorValues = new AtomicReference<Map<String, Long>>(
                new HashMap<String, Long>());

        @Override/*  w  w w.  j a  v  a 2 s .  c  om*/
        public boolean doMonitor(ServiceEmitter emitter) {
            final Map<String, Long> priorValues = this.priorValues.get();
            final Map<String, Long> currentValues = getCurrentValues();
            final ServiceMetricEvent.Builder builder = ServiceMetricEvent.builder();
            for (Map.Entry<String, Long> entry : currentValues.entrySet()) {
                emitter.emit(builder.setDimension("memcached metric", entry.getKey())
                        .build("query/cache/memcached/total", entry.getValue()));
                final Long prior = priorValues.get(entry.getKey());
                if (prior != null) {
                    emitter.emit(builder.setDimension("memcached metric", entry.getKey())
                            .build("query/cache/memcached/delta", entry.getValue() - prior));
                }
            }

            if (!this.priorValues.compareAndSet(priorValues, currentValues)) {
                log.error("Prior value changed while I was reporting! updating anyways");
                this.priorValues.set(currentValues);
            }
            return true;
        }

        private Map<String, Long> getCurrentValues() {
            final ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder();
            for (Map.Entry<String, AtomicLong> entry : counters.entrySet()) {
                builder.put(entry.getKey(), entry.getValue().get());
            }
            for (Map.Entry<String, AtomicLong> entry : meters.entrySet()) {
                builder.put(entry.getKey(), entry.getValue().get());
            }
            return builder.build();
        }
    };
    try {
        LZ4Transcoder transcoder = new LZ4Transcoder(config.getMaxObjectSize());

        // always use compression
        transcoder.setCompressionThreshold(0);

        OperationQueueFactory opQueueFactory;
        long maxQueueBytes = config.getMaxOperationQueueSize();
        if (maxQueueBytes > 0) {
            opQueueFactory = new MemcachedOperationQueueFactory(maxQueueBytes);
        } else {
            opQueueFactory = new LinkedOperationQueueFactory();
        }

        final Predicate<String> interesting = new Predicate<String>() {
            // See net.spy.memcached.MemcachedConnection.registerMetrics()
            private final Set<String> interestingMetrics = ImmutableSet.of(
                    "[MEM] Reconnecting Nodes (ReconnectQueue)",
                    //"[MEM] Shutting Down Nodes (NodesToShutdown)", // Busted
                    "[MEM] Request Rate: All", "[MEM] Average Bytes written to OS per write",
                    "[MEM] Average Bytes read from OS per read",
                    "[MEM] Average Time on wire for operations (s)",
                    "[MEM] Response Rate: All (Failure + Success + Retry)", "[MEM] Response Rate: Retry",
                    "[MEM] Response Rate: Failure", "[MEM] Response Rate: Success");

            @Override
            public boolean apply(@Nullable String input) {
                return input != null && interestingMetrics.contains(input);
            }
        };

        final MetricCollector metricCollector = new MetricCollector() {
            @Override
            public void addCounter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                counters.putIfAbsent(name, new AtomicLong(0L));

                if (log.isDebugEnabled()) {
                    log.debug("Add Counter [%s]", name);
                }
            }

            @Override
            public void removeCounter(String name) {
                if (log.isDebugEnabled()) {
                    log.debug("Ignoring request to remove [%s]", name);
                }
            }

            @Override
            public void incrementCounter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0));
                    counter = counters.get(name);
                }
                counter.incrementAndGet();

                if (log.isDebugEnabled()) {
                    log.debug("Increment [%s]", name);
                }
            }

            @Override
            public void incrementCounter(String name, int amount) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0));
                    counter = counters.get(name);
                }
                counter.addAndGet(amount);

                if (log.isDebugEnabled()) {
                    log.debug("Increment [%s] %d", name, amount);
                }
            }

            @Override
            public void decrementCounter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0));
                    counter = counters.get(name);
                }
                counter.decrementAndGet();

                if (log.isDebugEnabled()) {
                    log.debug("Decrement [%s]", name);
                }
            }

            @Override
            public void decrementCounter(String name, int amount) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong counter = counters.get(name);
                if (counter == null) {
                    counters.putIfAbsent(name, new AtomicLong(0L));
                    counter = counters.get(name);
                }
                counter.addAndGet(-amount);

                if (log.isDebugEnabled()) {
                    log.debug("Decrement [%s] %d", name, amount);
                }
            }

            @Override
            public void addMeter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                meters.putIfAbsent(name, new AtomicLong(0L));
                if (log.isDebugEnabled()) {
                    log.debug("Adding meter [%s]", name);
                }
            }

            @Override
            public void removeMeter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                if (log.isDebugEnabled()) {
                    log.debug("Ignoring request to remove meter [%s]", name);
                }
            }

            @Override
            public void markMeter(String name) {
                if (!interesting.apply(name)) {
                    return;
                }
                AtomicLong meter = meters.get(name);
                if (meter == null) {
                    meters.putIfAbsent(name, new AtomicLong(0L));
                    meter = meters.get(name);
                }
                meter.incrementAndGet();

                if (log.isDebugEnabled()) {
                    log.debug("Increment counter [%s]", name);
                }
            }

            @Override
            public void addHistogram(String name) {
                log.debug("Ignoring add histogram [%s]", name);
            }

            @Override
            public void removeHistogram(String name) {
                log.debug("Ignoring remove histogram [%s]", name);
            }

            @Override
            public void updateHistogram(String name, int amount) {
                log.debug("Ignoring update histogram [%s]: %d", name, amount);
            }
        };

        final ConnectionFactory connectionFactory = new MemcachedCustomConnectionFactoryBuilder()
                // 1000 repetitions gives us good distribution with murmur3_128
                // (approx < 5% difference in counts across nodes, with 5 cache nodes)
                .setKetamaNodeRepetitions(1000).setHashAlg(MURMUR3_128)
                .setProtocol(ConnectionFactoryBuilder.Protocol
                        .valueOf(StringUtils.toUpperCase(config.getProtocol())))
                .setLocatorType(
                        ConnectionFactoryBuilder.Locator.valueOf(StringUtils.toUpperCase(config.getLocator())))
                .setDaemon(true).setFailureMode(FailureMode.Cancel).setTranscoder(transcoder)
                .setShouldOptimize(true).setOpQueueMaxBlockTime(config.getTimeout())
                .setOpTimeout(config.getTimeout()).setReadBufferSize(config.getReadBufferSize())
                .setOpQueueFactory(opQueueFactory).setMetricCollector(metricCollector)
                .setEnableMetrics(MetricType.DEBUG) // Not as scary as it sounds
                .build();

        final List<InetSocketAddress> hosts = AddrUtil.getAddresses(config.getHosts());

        final Supplier<ResourceHolder<MemcachedClientIF>> clientSupplier;

        if (config.getNumConnections() > 1) {
            clientSupplier = new MemcacheClientPool(config.getNumConnections(),
                    new Supplier<MemcachedClientIF>() {
                        @Override
                        public MemcachedClientIF get() {
                            try {
                                return new MemcachedClient(connectionFactory, hosts);
                            } catch (IOException e) {
                                log.error(e, "Unable to create memcached client");
                                throw Throwables.propagate(e);
                            }
                        }
                    });
        } else {
            clientSupplier = Suppliers
                    .ofInstance(StupidResourceHolder.create(new MemcachedClient(connectionFactory, hosts)));
        }

        return new MemcachedCache(clientSupplier, config, monitor);
    } catch (IOException e) {
        throw Throwables.propagate(e);
    }
}