Example usage for java.util Collections synchronizedList

List of usage examples for java.util Collections synchronizedList

Introduction

In this page you can find the example usage for java.util Collections synchronizedList.

Prototype

public static <T> List<T> synchronizedList(List<T> list) 

Source Link

Document

Returns a synchronized (thread-safe) list backed by the specified list.

Usage

From source file:org.anothermonitor.ServiceReader.java

void addProcess(Map<String, Object> process) {
    // Integer      C.pId
    // String      C.pName
    // Integer      C.work
    // Integer      C.workBefore
    // List<Sring> C.finalValue
    if (mListSelected == null)
        mListSelected = Collections.synchronizedList(new ArrayList<Map<String, Object>>());
    mListSelected.add(process);//from   w w w  . j a  va  2s. c o  m
}

From source file:it.wami.map.mongodeploy.OsmSaxHandler.java

private void populateRelation(Relation relation) {
    Runnable r = new RelationRunnable(db, relation, relationsQueue);

    relationRunnables.add(r);//  w w w.  j a va2  s.c o m
    int current = (int) (readRelations % RELATIONS_CHUNK);

    if (current == RELATIONS_CHUNK - 1) {
        int cores = Runtime.getRuntime().availableProcessors();
        ExecutorService executorService = Executors.newFixedThreadPool(cores);
        for (Runnable currentRunnable : relationRunnables) {
            executorService.execute(currentRunnable);
        }
        relationRunnables = Collections.synchronizedList(new ArrayList<Runnable>());
        executorService.shutdown();
        while (!executorService.isTerminated()) {
        }

        saveEntry(relationsQueue, COLL_RELATIONS);
    }
}

From source file:voldemort.client.rebalance.AbstractZonedRebalanceTest.java

@Test(timeout = 600000)
public void testProxyGetDuringRebalancing() throws Exception {
    logger.info("Starting testProxyGetDuringRebalancing");
    try {/*from  ww  w.java 2 s .c om*/
        Cluster currentCluster = ServerTestUtils.getLocalZonedCluster(4, 2, new int[] { 0, 0, 1, 1 },
                new int[][] { { 0, 2, 4 }, { 6 }, { 1, 3, 5 }, { 7 } });
        Cluster tmpfinalCluster = UpdateClusterUtils.createUpdatedCluster(currentCluster, 3,
                Lists.newArrayList(2));
        final Cluster finalCluster = UpdateClusterUtils.createUpdatedCluster(tmpfinalCluster, 1,
                Lists.newArrayList(3));

        final List<Integer> serverList = Arrays.asList(0, 1, 2, 3);
        Map<String, String> configProps = new HashMap<String, String>();
        configProps.put("admin.max.threads", "5");
        final Cluster updatedCurrentCluster = startServers(currentCluster, storeDefFileWithReplication,
                serverList, configProps);

        ExecutorService executors = Executors.newFixedThreadPool(2);
        final AtomicBoolean rebalancingComplete = new AtomicBoolean(false);
        final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());

        String bootstrapUrl = getBootstrapUrl(updatedCurrentCluster, 0);
        int maxParallel = 2;
        final ClusterTestUtils.RebalanceKit rebalanceKit = ClusterTestUtils.getRebalanceKit(bootstrapUrl,
                maxParallel, finalCluster);

        try {

            populateData(currentCluster, rwStoreDefWithReplication);

            final SocketStoreClientFactory factory = new SocketStoreClientFactory(
                    new ClientConfig().setBootstrapUrls(getBootstrapUrl(currentCluster, 0)).setEnableLazy(false)
                            .setSocketTimeout(120, TimeUnit.SECONDS));

            final StoreClient<String, String> storeClientRW = new DefaultStoreClient<String, String>(
                    rwStoreDefWithReplication.getName(), null, factory, 3);

            final CountDownLatch latch = new CountDownLatch(2);
            // start get operation.
            executors.execute(new Runnable() {

                @Override
                public void run() {
                    try {
                        List<String> keys = new ArrayList<String>(testEntries.keySet());

                        while (!rebalancingComplete.get()) {
                            // should always able to get values.
                            int index = (int) (Math.random() * keys.size());

                            // should get a valid value
                            try {
                                Versioned<String> value = storeClientRW.get(keys.get(index));
                                assertNotSame("StoreClient get() should not return null.", null, value);
                                assertEquals("Value returned should be good",
                                        new Versioned<String>(testEntries.get(keys.get(index))), value);
                            } catch (Exception e) {
                                logger.error("Exception in proxy get thread", e);
                                e.printStackTrace();
                                exceptions.add(e);
                            }
                        }

                    } catch (Exception e) {
                        logger.error("Exception in proxy get thread", e);
                        exceptions.add(e);
                    } finally {
                        factory.close();
                        latch.countDown();
                    }
                }

            });

            executors.execute(new Runnable() {

                @Override
                public void run() {
                    try {

                        Thread.sleep(500);
                        rebalanceAndCheck(rebalanceKit.plan, rebalanceKit.controller,
                                Arrays.asList(0, 1, 2, 3));

                        Thread.sleep(500);
                        rebalancingComplete.set(true);
                        checkConsistentMetadata(finalCluster, serverList);

                    } catch (Exception e) {
                        exceptions.add(e);
                    } finally {
                        // stop servers
                        try {
                            stopServer(serverList);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        latch.countDown();
                    }
                }
            });

            latch.await();
            executors.shutdown();
            executors.awaitTermination(300, TimeUnit.SECONDS);

            // check No Exception
            if (exceptions.size() > 0) {
                for (Exception e : exceptions) {
                    e.printStackTrace();
                }
                fail("Should not see any exceptions.");
            }
        } finally {
            // stop servers
            stopServer(serverList);
        }
    } catch (AssertionError ae) {
        logger.error("Assertion broken in testProxyGetDuringRebalancing ", ae);
        throw ae;
    }
}

From source file:voldemort.client.rebalance.AbstractRebalanceTest.java

@Test
public void testProxyGetDuringRebalancing() throws Exception {
    final Cluster currentCluster = ServerTestUtils.getLocalCluster(2,
            new int[][] { { 0, 1, 2, 3, 4, 5, 6 }, { 7, 8 } });

    final Cluster targetCluster = RebalanceUtils.createUpdatedCluster(currentCluster, 1,
            Lists.newArrayList(2, 3));/*from www .  ja  v  a2s .co  m*/
    // start servers 0 , 1 only
    final List<Integer> serverList = Arrays.asList(0, 1);
    final Cluster updatedCurrentCluster = startServers(currentCluster, storeDefFileWithReplication, serverList,
            null);
    final Cluster updatedTargetCluster = updateCluster(targetCluster);

    ExecutorService executors = Executors.newFixedThreadPool(2);
    final AtomicBoolean rebalancingToken = new AtomicBoolean(false);
    final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());

    RebalanceClientConfig rebalanceClientConfig = new RebalanceClientConfig();
    rebalanceClientConfig.setMaxParallelRebalancing(2);

    final RebalanceController rebalanceClient = new RebalanceController(
            getBootstrapUrl(updatedCurrentCluster, 0), rebalanceClientConfig);

    // Populate the two stores
    populateData(updatedCurrentCluster, roStoreDefWithReplication, rebalanceClient.getAdminClient(), true);

    populateData(updatedCurrentCluster, rwStoreDefWithReplication, rebalanceClient.getAdminClient(), false);

    final SocketStoreClientFactory factory = new SocketStoreClientFactory(
            new ClientConfig().setBootstrapUrls(getBootstrapUrl(updatedCurrentCluster, 0)).setEnableLazy(false)
                    .setSocketTimeout(120, TimeUnit.SECONDS));

    final StoreClient<String, String> storeClientRW = new DefaultStoreClient<String, String>(testStoreNameRW,
            null, factory, 3);

    final StoreClient<String, String> storeClientRO = new DefaultStoreClient<String, String>(testStoreNameRO,
            null, factory, 3);

    // start get operation.
    executors.execute(new Runnable() {

        public void run() {
            try {
                List<String> keys = new ArrayList<String>(testEntries.keySet());

                int nRequests = 0;
                while (!rebalancingToken.get()) {
                    // should always able to get values.
                    int index = (int) (Math.random() * keys.size());

                    // should get a valid value
                    try {
                        nRequests++;
                        Versioned<String> value = storeClientRW.get(keys.get(index));
                        assertNotSame("StoreClient get() should not return null.", null, value);
                        assertEquals("Value returned should be good",
                                new Versioned<String>(testEntries.get(keys.get(index))), value);

                        value = storeClientRO.get(keys.get(index));
                        assertNotSame("StoreClient get() should not return null.", null, value);
                        assertEquals("Value returned should be good",
                                new Versioned<String>(testEntries.get(keys.get(index))), value);

                    } catch (Exception e) {
                        e.printStackTrace();
                        exceptions.add(e);
                    }
                }

            } catch (Exception e) {
                exceptions.add(e);
            } finally {
                factory.close();
            }
        }

    });

    executors.execute(new Runnable() {

        public void run() {
            try {

                Thread.sleep(500);
                rebalanceAndCheck(updatedCurrentCluster, updatedTargetCluster, storeDefWithReplication,
                        rebalanceClient, Arrays.asList(0, 1));
                Thread.sleep(500);
                rebalancingToken.set(true);
                checkConsistentMetadata(updatedTargetCluster, serverList);

            } catch (Exception e) {
                exceptions.add(e);
            } finally {
                // stop servers
                try {
                    stopServer(serverList);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    });

    executors.shutdown();
    executors.awaitTermination(300, TimeUnit.SECONDS);

    // check No Exception
    if (exceptions.size() > 0) {
        for (Exception e : exceptions) {
            e.printStackTrace();
        }
        fail("Should not see any exceptions.");
    }
}

From source file:net.sourceforge.fenixedu.domain.accounting.report.events.EventReportQueueJob.java

private SheetData<AccountingTransactionBean> allTransactions(final StringBuilder errors) {

    List<String> allEventsExternalIds = getAllEventsExternalIds();
    logger.info(String.format("%s events (transactions) to process", allEventsExternalIds.size()));

    Integer blockRead = 0;/*  w w  w.j  a v  a2  s.co  m*/

    final List<AccountingTransactionBean> result = Collections
            .synchronizedList(new ArrayList<AccountingTransactionBean>());

    while (blockRead < allEventsExternalIds.size()) {
        Integer inc = BLOCK;

        if (blockRead + inc >= allEventsExternalIds.size()) {
            inc = allEventsExternalIds.size() - blockRead;
        }

        final List<String> block = allEventsExternalIds.subList(blockRead, blockRead + inc);
        blockRead += inc;

        Thread thread = new Thread() {

            @Override
            @Atomic(mode = TxMode.READ)
            public void run() {
                for (String oid : block) {
                    Event event = FenixFramework.getDomainObject(oid);
                    try {
                        if (!isAccountingEventForReport(event)) {
                            continue;
                        }
                        result.addAll(writeTransactionInformation(event));
                    } catch (Throwable e) {
                        errors.append(getErrorLine(event, e));
                    }
                }
            }
        };

        thread.start();

        try {
            thread.join();
        } catch (InterruptedException e) {
        }

        logger.info(String.format("Read %s events", blockRead));
    }

    return new SheetData<AccountingTransactionBean>(result) {

        @Override
        protected void makeLine(AccountingTransactionBean bean) {

            addCell("Identificador", bean.eventExternalId);
            addCell("Data do pagamento", bean.whenRegistered);
            addCell("Data de entrada do pagamento", bean.whenProcessed);
            addCell("Nome da entidade devedora", bean.debtPartyName);
            addCell("Contribuinte da entidade devedora", bean.debtSocialSecurityNumber);
            addCell("Nome da entidade credora", bean.credPartyName);
            addCell("Contribuinte da entidade credora", bean.credSocialSecurityNumber);
            addCell("Montante inicial", bean.originalAmount);
            addCell("Montante ajustado", bean.amountWithAdjustment);
            addCell("Modo de pagamento", bean.paymentMode);
            addCell("Data do ajuste", bean.whenAdjustmentRegistered);
            addCell("Data de entrada do ajuste", bean.whenAdjustmentProcessed);
            addCell("Montante do ajuste", bean.adjustmentAmount);
            addCell("Justificao", bean.comments);

        }

    };
}

From source file:voldemort.client.rebalance.ZonedRebalanceNonContiguousZonesTest.java

@Test(timeout = 600000)
public void testProxyGetDuringRebalancing() throws Exception {
    logger.info("Starting testProxyGetDuringRebalancing");
    try {//from   w ww . j  a  v a  2 s.  c o m

        int zoneIds[] = new int[] { 1, 3 };
        int nodesPerZone[][] = new int[][] { { 3, 4 }, { 9, 10 } };
        int partitionMap[][] = new int[][] { { 0, 2, 4 }, { 6 }, { 1, 3, 5 }, { 7 } };
        Cluster currentCluster = ServerTestUtils.getLocalNonContiguousZonedCluster(zoneIds, nodesPerZone,
                partitionMap, ClusterTestUtils.getClusterPorts());
        Cluster tmpfinalCluster = UpdateClusterUtils.createUpdatedCluster(currentCluster, 10,
                Lists.newArrayList(2));
        final Cluster finalCluster = UpdateClusterUtils.createUpdatedCluster(tmpfinalCluster, 4,
                Lists.newArrayList(3));

        // start servers
        final List<Integer> serverList = Arrays.asList(3, 4, 9, 10);
        Map<String, String> configProps = new HashMap<String, String>();
        configProps.put("admin.max.threads", "5");
        final Cluster updatedCurrentCluster = startServers(currentCluster, storeDefFileWithReplication,
                serverList, configProps);

        ExecutorService executors = Executors.newFixedThreadPool(2);
        final AtomicBoolean rebalancingComplete = new AtomicBoolean(false);
        final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());

        String bootstrapUrl = getBootstrapUrl(updatedCurrentCluster, 3);
        int maxParallel = 2;
        final ClusterTestUtils.RebalanceKit rebalanceKit = ClusterTestUtils.getRebalanceKit(bootstrapUrl,
                maxParallel, finalCluster);

        try {

            populateData(currentCluster, rwStoreDefWithReplication);

            final SocketStoreClientFactory factory = new SocketStoreClientFactory(
                    new ClientConfig().setBootstrapUrls(getBootstrapUrl(currentCluster, 3)).setEnableLazy(false)
                            .setSocketTimeout(120, TimeUnit.SECONDS));

            final StoreClient<String, String> storeClientRW = new DefaultStoreClient<String, String>(
                    rwStoreDefWithReplication.getName(), null, factory, 3);

            final CountDownLatch latch = new CountDownLatch(2);
            // start get operation.
            executors.execute(new Runnable() {

                @Override
                public void run() {
                    try {
                        List<String> keys = new ArrayList<String>(testEntries.keySet());

                        while (!rebalancingComplete.get()) {
                            // should always able to get values.
                            int index = (int) (Math.random() * keys.size());

                            // should get a valid value
                            try {
                                Versioned<String> value = storeClientRW.get(keys.get(index));
                                assertNotSame("StoreClient get() should not return null.", null, value);
                                assertEquals("Value returned should be good",
                                        new Versioned<String>(testEntries.get(keys.get(index))), value);
                            } catch (Exception e) {
                                logger.error("Exception in proxy get thread", e);
                                e.printStackTrace();
                                exceptions.add(e);
                            }
                        }

                    } catch (Exception e) {
                        logger.error("Exception in proxy get thread", e);
                        exceptions.add(e);
                    } finally {
                        factory.close();
                        latch.countDown();
                    }
                }

            });

            executors.execute(new Runnable() {

                @Override
                public void run() {
                    try {

                        Thread.sleep(500);
                        rebalanceAndCheck(rebalanceKit.plan, rebalanceKit.controller,
                                Arrays.asList(3, 4, 9, 10));

                        Thread.sleep(500);
                        rebalancingComplete.set(true);
                        checkConsistentMetadata(finalCluster, serverList);

                    } catch (Exception e) {
                        exceptions.add(e);
                    } finally {
                        // stop servers
                        try {
                            stopServer(serverList);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        latch.countDown();
                    }
                }
            });

            latch.await();
            executors.shutdown();
            executors.awaitTermination(300, TimeUnit.SECONDS);

            // check No Exception
            if (exceptions.size() > 0) {
                for (Exception e : exceptions) {
                    e.printStackTrace();
                }
                fail("Should not see any exceptions.");
            }
        } finally {
            // stop servers
            stopServer(serverList);
        }
    } catch (AssertionError ae) {
        logger.error("Assertion broken in testProxyGetDuringRebalancing ", ae);
        throw ae;
    }
}

From source file:com.healthcit.cacure.businessdelegates.GeneratedModuleDataManager.java

@SuppressWarnings({ "unchecked" })
private JSONObject generateRandomAnswerValueForUniqueKey(Map question, Map uniqueKey,
        Map<String, JSONObject> lastUniqueKey, Map<Object, List<Object>> previousAnswers, Object groupId) {
    JSONObject randomAnswerValueObject;//from   w w  w .jav a2s. com

    // Get the question's UUID
    String questionUUID = (String) question.get(UUID_VALUE);

    // If a random answer has already been generated for this question
    // (example, if this is a unique-per-all-modules question that is also
    // a unique-per-entity question, and the unique-per-entity question was processed first),
    // then simply copy the previously generated random answer for this unique key

    if (uniqueKey.containsKey(questionUUID)) {
        randomAnswerValueObject = (JSONObject) uniqueKey.get(questionUUID);

        return randomAnswerValueObject;
    }

    // else:
    else {
        // Get the previously generated unique keys as an ordered list
        LinkedList<Map.Entry> previousUniqueKeys = new LinkedList(((LinkedHashMap) previousAnswers).entrySet());

        // Get the value of the field which identifies the last unique group which was processed
        Map.Entry last = (previousUniqueKeys.isEmpty() ? null : previousUniqueKeys.getLast());

        List list = (last == null ? null : (List) last.getValue());

        Object lastGroupId = list == null ? null : Collections.synchronizedList(list).get(list.size() - 1);

        // If the current groupId matches the lastGroupId,
        // then it means that the same answer value should be used for the current unique key
        // ( since uniqueness is determined by the group )
        if (groupId.equals(lastGroupId)) {
            randomAnswerValueObject = new JSONObject();

            randomAnswerValueObject.putAll(lastUniqueKey.get(questionUUID));

            return randomAnswerValueObject;
        }

        // Otherwise, a new group is being processed, so generate a new random answer value
        else {
            // Determine the last generated random value for this question
            JSONObject lastRandomAnswerValueObject = lastUniqueKey.get(questionUUID);

            Object lastRandomAnswerValue = lastRandomAnswerValueObject == null ? null
                    : getAnswerValue(lastRandomAnswerValueObject);

            return generateRandomAnswerValue(question, lastRandomAnswerValue,
                    (lastRandomAnswerValue == null ? Algorithm.PSEUDORANDOM : Algorithm.EVEN));
        }
    }
}

From source file:uk.bl.dpt.qa.gui.DissimilarGUIThread.java

/**
 * Open input csv file/* w w  w  . j a v  a 2s  . c om*/
 * @param pFile file to load from
 */
private void internalOpenFile(File pFile) {
    init();
    gResults = Collections.synchronizedList(new LinkedList<CheckResult>());
    try {
        BufferedReader buf = new BufferedReader(new FileReader(pFile));
        while (buf.ready()) {
            CheckResult result = new CheckResult();
            String[] line = buf.readLine().split(",");
            if (line == null || line.length != 2) {
                continue;
            }
            result.setFileOne(new File(line[0]));
            result.setFileTwo(new File(line[1]));
            gResults.add(result);
        }
        buf.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //initialise the results array to hold the correct number of results

    if (checkboxGenerateOnLoad.selectedProperty().get()) {
        //start a background thread to calculate all the values
        internalStartBackgroundLoadThread();
    }

    //load the first image
    internalDisplayPair(gCurrentRecord);
}

From source file:com.igormaznitsa.jute.JuteMojo.java

private int executeNextTestsFromList(final List<String> logStrings, final int maxTestNameLength,
        final String testClassPath, final List<TestContainer> testContainers, final int startIndex,
        final AtomicInteger startedCounter, final AtomicInteger errorCounter,
        final AtomicInteger skippedCounter) throws Exception {
    final List<TestContainer> toExecute = new ArrayList<TestContainer>();

    int detectedOrder = -1;

    for (int i = startIndex; i < testContainers.size(); i++) {
        final TestContainer c = testContainers.get(i);
        if (detectedOrder < 0) {
            if (c.getOrder() < 0) {
                toExecute.add(c);//from w w w  .  j  a v a 2 s  .c  om
            } else {
                if (toExecute.isEmpty()) {
                    detectedOrder = c.getOrder();
                    toExecute.add(c);
                } else {
                    break;
                }
            }
        } else {
            if (c.getOrder() == detectedOrder) {
                toExecute.add(c);
            } else {
                break;
            }
        }
    }
    final CountDownLatch counterDown;

    if (detectedOrder >= 0 && toExecute.size() > 1) {
        counterDown = new CountDownLatch(toExecute.size());
    } else {
        counterDown = null;
    }

    final List<Throwable> thrownErrors = Collections.synchronizedList(new ArrayList<Throwable>());

    for (final TestContainer container : toExecute) {
        final Runnable run = new Runnable() {
            @Override
            public void run() {
                final long startTime = System.currentTimeMillis();
                try {
                    getLog().debug("Start execution: " + container.toString());
                    startedCounter.incrementAndGet();
                    final TestResult result = container.executeTest(getLog(), onlyAnnotated, maxTestNameLength,
                            testClassPath, javaProperties, env);
                    final long endTime = System.currentTimeMillis();
                    switch (result) {
                    case ERROR:
                    case TIMEOUT: {
                        errorCounter.incrementAndGet();
                    }
                        break;
                    case SKIPPED: {
                        skippedCounter.incrementAndGet();
                    }
                        break;
                    }

                    if (logStrings != null) {
                        final boolean printConsoleLog = result != TestResult.OK || container.isPrintConsole();
                        synchronized (logStrings) {
                            logStrings.addAll(makeTestResultReference(counterDown == null, container,
                                    endTime - startTime, maxTestNameLength, result,
                                    (printConsoleLog ? container.getLastTerminalOut() : null)));
                        }
                    }
                } catch (Throwable thr) {
                    getLog().debug("Error during execution " + container.toString(), thr);
                    thrownErrors.add(thr);
                } finally {
                    getLog().debug("End execution: " + container.toString());
                    if (counterDown != null) {
                        counterDown.countDown();
                    }
                }
            }
        };
        if (counterDown == null) {
            getLog().debug("Sync.execution: " + container.toString());
            run.run();
        } else {
            getLog().debug("Async.execution: " + container.toString());
            CACHED_EXECUTOR.execute(run);
        }
    }
    if (counterDown != null) {
        try {
            counterDown.await();
        } catch (InterruptedException ex) {
            getLog().error(ex);
        }
    }
    if (!thrownErrors.isEmpty()) {
        for (final Throwable thr : thrownErrors) {
            getLog().error(thr);
        }
    }

    return toExecute.size();
}

From source file:voldemort.store.routed.ThreadPoolRoutedStore.java

@Override
public void put(final ByteArray key, final Versioned<byte[]> versioned, final byte[] transforms)
        throws VoldemortException {
    long startNs = System.nanoTime();
    StoreUtils.assertValidKey(key);/*  w w  w . jav  a  2  s.  com*/
    final List<Node> nodes = availableNodes(routingStrategy.routeRequest(key.get()));

    // quickly fail if there aren't enough nodes to meet the requirement
    final int numNodes = nodes.size();
    if (numNodes < this.storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException("Only " + numNodes + " nodes in preference list, but "
                + this.storeDef.getRequiredWrites() + " writes required.");

    // A count of the number of successful operations
    final AtomicInteger successes = new AtomicInteger(0);

    // A list of thrown exceptions, indicating the number of failures
    final List<Exception> failures = Collections.synchronizedList(new ArrayList<Exception>(1));

    // If requiredWrites > 0 then do a single blocking write to the first
    // live node in the preference list if this node throws an
    // ObsoleteVersionException allow it to propagate
    Node master = null;
    int currentNode = 0;
    Versioned<byte[]> versionedCopy = null;
    for (; currentNode < numNodes; currentNode++) {
        Node current = nodes.get(currentNode);
        long startNsLocal = System.nanoTime();
        try {
            versionedCopy = incremented(versioned, current.getId());
            innerStores.get(current.getId()).put(key, versionedCopy, transforms);
            successes.getAndIncrement();
            recordSuccess(current, startNsLocal);
            master = current;
            break;
        } catch (UnreachableStoreException e) {
            recordException(current, startNsLocal, e);
            failures.add(e);
        } catch (VoldemortApplicationException e) {
            throw e;
        } catch (Exception e) {
            failures.add(e);
        }
    }

    if (successes.get() < 1)
        throw new InsufficientOperationalNodesException("No master node succeeded!",
                failures.size() > 0 ? failures.get(0) : null);
    else
        currentNode++;

    // A semaphore indicating the number of completed operations
    // Once inititialized all permits are acquired, after that
    // permits are released when an operation is completed.
    // semaphore.acquire(n) waits for n operations to complete
    final Versioned<byte[]> finalVersionedCopy = versionedCopy;
    final Semaphore semaphore = new Semaphore(0, false);
    // Add the operations to the pool
    int attempts = 0;
    for (; currentNode < numNodes; currentNode++) {
        attempts++;
        final Node node = nodes.get(currentNode);
        this.executor.execute(new Runnable() {

            @Override
            public void run() {
                long startNsLocal = System.nanoTime();
                try {
                    innerStores.get(node.getId()).put(key, finalVersionedCopy, transforms);
                    successes.incrementAndGet();
                    recordSuccess(node, startNsLocal);
                } catch (UnreachableStoreException e) {
                    recordException(node, startNsLocal, e);
                    failures.add(e);
                } catch (ObsoleteVersionException e) {
                    // ignore this completely here
                    // this means that a higher version was able
                    // to write on this node and should be termed as clean
                    // success.
                } catch (VoldemortApplicationException e) {
                    throw e;
                } catch (Exception e) {
                    logger.warn("Error in PUT on node " + node.getId() + "(" + node.getHost() + ")", e);
                    failures.add(e);
                } finally {
                    // signal that the operation is complete
                    semaphore.release();
                }
            }
        });
    }

    // Block until we get enough completions
    int blockCount = Math.min(storeDef.getPreferredWrites() - 1, attempts);
    boolean noTimeout = blockOnPut(startNs, semaphore, 0, blockCount, successes, storeDef.getPreferredWrites());

    if (successes.get() < storeDef.getRequiredWrites()) {
        /*
         * We don't have enough required writes, but we haven't timed out
         * yet, so block a little more if there are healthy nodes that can
         * help us achieve our target.
         */
        if (noTimeout) {
            int startingIndex = blockCount - 1;
            blockCount = Math.max(storeDef.getPreferredWrites() - 1, attempts);
            blockOnPut(startNs, semaphore, startingIndex, blockCount, successes, storeDef.getRequiredWrites());
        }
        if (successes.get() < storeDef.getRequiredWrites())
            throw new InsufficientOperationalNodesException(successes.get() + " writes succeeded, but "
                    + this.storeDef.getRequiredWrites() + " are required.", failures);
    }

    // Okay looks like it worked, increment the version for the caller
    VectorClock versionedClock = (VectorClock) versioned.getVersion();
    versionedClock.incrementVersion(master.getId(), time.getMilliseconds());
}