Example usage for java.util Deque peekLast

List of usage examples for java.util Deque peekLast

Introduction

In this page you can find the example usage for java.util Deque peekLast.

Prototype

E peekLast();

Source Link

Document

Retrieves, but does not remove, the last element of this deque, or returns null if this deque is empty.

Usage

From source file:Main.java

public static void main(String[] args) {

    Deque<Integer> deque = new ArrayDeque<Integer>(8);

    deque.add(1);// w ww. j a  va  2s  .c o m
    deque.add(2);
    deque.add(3);
    deque.add(4);

    int retval = deque.peekLast();
    System.out.println("Retrieved Element is " + retval);

    System.out.println(deque);
}

From source file:co.cask.cdap.gateway.handlers.metrics.MetricsSuiteTestBase.java

public static void stop() {
    collectionService.stopAndWait();//from  w w  w.j  av a 2s  .c  o m

    Deque<File> files = Lists.newLinkedList();
    files.add(dataDir);

    File file = files.peekLast();
    while (file != null) {
        File[] children = file.listFiles();
        if (children == null || children.length == 0) {
            files.pollLast().delete();
        } else {
            Collections.addAll(files, children);
        }
        file = files.peekLast();
    }
}

From source file:com.mgmtp.perfload.core.console.status.FileStatusTransformer.java

private void processStatusInfo(final Map<StatusInfoKey, StatusInfo> statusInfoMap,
        final Map<StatusInfoKey, Deque<ThreadActivity>> threadActivitiesMap) {
    PrintWriter pr = null;/*from ww  w. j a  v a 2  s .c om*/
    try {
        pr = new PrintWriter(statusFile, encoding);
        pr.println(HR);
        pr.println(HEADER);
        pr.println(HR);

        Set<StatusInfoKey> sortedKeys = newTreeSet(statusInfoMap.keySet());

        int threadsFinished = 0;
        for (StatusInfoKey key : sortedKeys) {
            StatusInfo statusInfo = statusInfoMap.get(key);

            if (statusInfo.getFinished() != null && statusInfo.getFinished()) {
                threadsFinished++;
            }

            StrBuilder sb = new StrBuilder(200);

            sb.append(LINE_START);
            sb.appendFixedWidthPadLeft(statusInfo.getDaemonId(), DAEMON_ID.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadLeft(statusInfo.getProcessId(), PROCESS_ID.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadLeft(statusInfo.getThreadId(), THREAD_ID.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadRight(statusInfo.getOperation(), OPERATION.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadRight(statusInfo.getTarget(), TARGET.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadRight(statusInfo.getFinished(), FINISHED.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadRight(statusInfo.getStackTrace() != null, ERROR.length(), ' ');
            sb.append(DELIMITER);
            sb.appendFixedWidthPadRight(
                    statusInfo.getError() != null ? statusInfo.getError() ? "ERROR" : "SUCCESS" : "",
                    RESULT.length(), ' ');
            sb.append(LINE_END);

            pr.println(sb);
        }

        pr.println(HR);

        StrBuilder sb = new StrBuilder(HR.length);
        sb.append(LINE_START);

        int activeThreads = 0;
        for (Deque<ThreadActivity> ta : threadActivitiesMap.values()) {
            activeThreads += ta.peekLast().getActiveThreads();
        }
        sb.appendFixedWidthPadRight("Currently active client threads: " + activeThreads,
                HR.length - LINE_START.length() - LINE_END.length(), ' ');
        sb.append(LINE_END);
        pr.println(sb);

        sb = new StrBuilder(HR.length);
        sb.append(LINE_START);
        maxConcurrentThreads = max(maxConcurrentThreads, activeThreads);
        sb.appendFixedWidthPadRight("Maximum concurrent client threads: " + maxConcurrentThreads,
                HR.length - LINE_START.length() - LINE_END.length(), ' ');
        sb.append(LINE_END);
        pr.println(sb);

        sb = new StrBuilder(HR.length);
        sb.append(LINE_START);
        sb.appendFixedWidthPadRight("Total threads finished: " + threadsFinished + "/" + totalThreadCount,
                HR.length - LINE_START.length() - LINE_END.length(), ' ');
        sb.append(LINE_END);
        pr.println(sb);

        pr.println(HR);
    } catch (IOException ex) {
        log.error("Error writing load test status to file: {}", statusFile, ex);
    } finally {
        IOUtils.closeQuietly(pr);
    }
}

From source file:edu.berkeley.compbio.phyloutils.HugenholtzTaxonomyService.java

private synchronized Integer commonAncestor(Set<Deque<Integer>> paths) throws NoSuchNodeException {
    if (paths.size() == 1) {
        final Deque<Integer> path = paths.iterator().next();
        return path.getLast();
    } else {/* w  w  w.  j a  v  a  2  s.co m*/
        assert paths.size() > 1;
        //   throw new PhyloUtilsRuntimeException("Taxonomy path not unique : " + DSStringUtils.join(taxa, "; "));
        Set<Integer> leafIds = new HashSet<Integer>();
        for (Deque<Integer> path : paths) {
            leafIds.add(path.peekLast());
        }
        BasicRootedPhylogeny<Integer> theIntegerTree = (BasicRootedPhylogeny<Integer>) theIntegerTreeStub.get();

        return theIntegerTree.commonAncestor(leafIds, 0.75);
    }
}

From source file:de.themoep.simpleteampvp.games.SimpleTeamPvPGame.java

/**
 * Balance the teams/*from   ww  w.ja v a  2s.c  om*/
 * @return <tt>true</tt> if game is in GameState.JOINING and players can be balanced
 */
public boolean balance() {
    if (getState() != GameState.JOINING)
        return false;

    plugin.getServer()
            .broadcastMessage(ChatColor.GREEN + "Ausbalancieren und Auffllen der Teams gestartet...");

    Map<Player, String> beforeBalance = new HashMap<>();
    List<Player> playersToJoin = new ArrayList<>();
    for (Player player : plugin.getServer().getOnlinePlayers()) {
        if (player.hasPermission(SimpleTeamPvP.BYPASS_PERM) || player.getGameMode() == GameMode.CREATIVE
                || player.getGameMode() == GameMode.SPECTATOR)
            continue;
        TeamInfo team = getTeam(player);
        if (team == null) {
            if (config.getRandomRegion() == null || config.getRandomRegion().contains(player.getLocation()))
                playersToJoin.add(player);
            beforeBalance.put(player, "");
        } else {
            beforeBalance.put(player, team.getName());
        }
    }
    plugin.getLogger().log(Level.INFO, "Players to join: " + playersToJoin.size());

    int totalPlayers = playersToJoin.size();
    for (TeamInfo team : config.getTeams().values()) {
        totalPlayers += team.getSize();
    }
    plugin.getLogger().log(Level.INFO, "Number of teams: " + config.getTeams().size());
    double perfectSize = (double) totalPlayers / (double) config.getTeams().size();

    plugin.getLogger().log(Level.INFO, "perfectSize: " + perfectSize);

    if (plugin.getServerTags() != null) {
        // Team key -> Tag
        Map<String, String> teamTags = new HashMap<>();

        for (TeamInfo team : config.getTeams().values()) {

            Map<String, Integer> tags = new HashMap<>();
            for (String playerName : team.getScoreboardTeam().getEntries()) {
                Player player = plugin.getServer().getPlayer(playerName);
                if (player == null)
                    continue;

                String tag = "no server";
                ServerInfo serverInfo = plugin.getServerTags().getPlayerServer(player);
                if (serverInfo != null) {
                    tag = serverInfo.getTag();
                }
                if (!tags.containsKey(tag)) {
                    tags.put(tag, 0);
                }
                tags.put(tag, tags.get(tag) + 1);
            }

            String teamTag = "no server";
            int tagCount = 0;
            for (Map.Entry<String, Integer> entry : tags.entrySet()) {
                if (entry.getValue() > tagCount) {
                    tagCount = entry.getValue();
                    teamTag = entry.getKey();
                }
            }

            teamTags.put(team.getName(), teamTag);
        }

        for (TeamInfo team : config.getTeams().values()) {
            // Filter out players that come from another server than the majority of the team
            // and remove them as long as the team is larger than the perfect size
            for (String playerName : team.getScoreboardTeam().getEntries()) {
                if (team.getSize() <= perfectSize + 0.5)
                    break;

                Player player = plugin.getServer().getPlayer(playerName);
                if (player == null)
                    continue;

                String tag = "no server";
                ServerInfo serverInfo = plugin.getServerTags().getPlayerServer(player);
                if (serverInfo != null) {
                    tag = serverInfo.getTag();
                }

                if (tag.equals(teamTags.get(team.getName())))
                    continue;

                plugin.getLogger().log(Level.INFO,
                        "[ST] Removed " + player.getName() + " from " + team.getName() + " (Step 1)");

                team.removePlayer(player);
                playersToJoin.add(player);
            }

            // Team still larger than the perfect size? Remove last joined player
            Deque<String> teamMates = new ArrayDeque<>(team.getScoreboardTeam().getEntries());
            while (team.getSize() > perfectSize + 0.5) {
                String name = teamMates.peekLast();
                Player player = plugin.getServer().getPlayer(name);
                if (player == null)
                    continue;

                team.removePlayer(player);
                plugin.getLogger().log(Level.INFO,
                        "[ST] Removed " + player.getName() + " from " + team.getName() + " (Step 2)");
                teamMates.pollLast();
                playersToJoin.add(player);
            }
        }

        // Add rest of players to teams from their server
        Iterator<Player> playerIterator = playersToJoin.iterator();
        while (playerIterator.hasNext()) {
            Player player = playerIterator.next();
            ServerInfo serverInfo = plugin.getServerTags().getPlayerServer(player);
            if (serverInfo != null && teamTags.containsValue(serverInfo.getTag())) {
                for (TeamInfo team : config.getTeams().values()) {
                    if (team.getSize() < perfectSize - 0.5 && teamTags.containsKey(team.getName())
                            && teamTags.get(team.getName()).equals(serverInfo.getTag())) {
                        team.addPlayer(player);
                        plugin.getLogger().log(Level.INFO,
                                "[ST] Added " + player.getName() + " to " + team.getName());
                        playerIterator.remove();
                        break;
                    }
                }
            }
        }
        plugin.getLogger().log(Level.INFO, "Players to join after servertags: " + playersToJoin.size());
    }

    // Remove players from teams that have more than the perfect size
    for (TeamInfo team : config.getTeams().values()) {
        for (String playerName : team.getScoreboardTeam().getEntries()) {
            if (team.getSize() <= perfectSize + 0.5)
                break;

            Player player = plugin.getServer().getPlayer(playerName);
            if (player == null)
                continue;

            plugin.getLogger().log(Level.INFO, "Removed " + player.getName() + " from " + team.getName());

            team.removePlayer(player);
            playersToJoin.add(player);
        }
    }

    Iterator<Player> playerIterator = playersToJoin.iterator();
    for (TeamInfo team : config.getTeams().values()) {
        while (playerIterator.hasNext()) {
            if (team.getSize() >= perfectSize - 0.5)
                break;

            Player player = playerIterator.next();
            team.addPlayer(player);
            plugin.getLogger().log(Level.INFO, "Added " + player.getName() + " to " + team.getName());
            playerIterator.remove();
        }
    }

    if (playerIterator.hasNext()) {
        plugin.getLogger().log(Level.INFO, "Adding " + playersToJoin.size()
                + " remaining players to teams according to their player count:");

        List<TeamInfo> teams = new ArrayList<>(config.getTeams().values());
        teams.sort((t1, t2) -> Integer.compare(t2.getSize(), t1.getSize()));

        for (TeamInfo team : teams) {
            while (playerIterator.hasNext()) {
                if (team.getSize() > perfectSize)
                    break;

                Player player = playerIterator.next();
                team.addPlayer(player);
                plugin.getLogger().log(Level.INFO,
                        "Added remaining player " + player.getName() + " to " + team.getName());
                playerIterator.remove();
            }
        }
    }

    if (playerIterator.hasNext()) {
        plugin.getLogger().log(Level.INFO,
                "Adding " + playersToJoin.size() + " remaining players to totally random teams:");
        Random r = new Random();
        List<TeamInfo> teams = new ArrayList<>(config.getTeams().values());
        while (playerIterator.hasNext()) {
            Player player = playerIterator.next();
            TeamInfo team = teams.get(r.nextInt(teams.size()));
            team.addPlayer(player);
            plugin.getLogger().log(Level.INFO,
                    "Added player " + player.getName() + " to " + team.getName() + " by random");
            playerIterator.remove();
        }
    }
    plugin.getLogger().log(Level.INFO, "All players joined! (" + playersToJoin.size() + ")");

    for (Map.Entry<Player, String> entry : beforeBalance.entrySet()) {
        TeamInfo team = getTeam(entry.getKey());
        if (team != null && !team.getName().equals(entry.getValue())) {
            Player player = null;
            for (Iterator<String> it = team.getScoreboardTeam().getEntries().iterator(); player == null
                    && it.hasNext();) {
                player = plugin.getServer().getPlayer(it.next());
            }
            if (player != null && team.getJoinRegion().contains(player.getLocation())) {
                entry.getKey().teleport(player);
            } else {
                entry.getKey().teleport(team.getJoinRegion().calculateMiddle().getLocation());
            }
        }
    }

    plugin.getServer().broadcastMessage(ChatColor.GREEN + "Teams ausbalanciert und aufgefllt!");

    state = GameState.WAITING;
    return true;
}

From source file:hudson.plugins.project_inheritance.projects.InheritanceProject.java

public SCM getScm(IMode mode) {
    InheritanceGovernor<SCM> gov = new InheritanceGovernor<SCM>("scm", SELECTOR.MISC, this) {
        @Override//from w  w  w.  j  a  v a  2  s.  c  o  m
        protected SCM castToDestinationType(Object o) {
            return (o instanceof SCM) ? (SCM) o : null;
        }

        @Override
        public SCM getRawField(InheritanceProject ip) {
            return ip.getRawScm();
        }

        @Override
        protected SCM reduceFromFullInheritance(Deque<SCM> list) {
            if (list == null || list.isEmpty()) {
                return new NullSCM();
            }
            //Return the SCM that was defined last and is not a NullSCM
            Iterator<SCM> iter = list.descendingIterator();
            while (iter.hasNext()) {
                SCM scm = iter.next();
                if (scm != null && !(scm instanceof NullSCM)) {
                    return scm;
                }
            }
            //All SCMs are NullSCMs; so it does not matter which one to return
            return list.peekLast();
        }
    };

    SCM scm = gov.retrieveFullyDerivedField(this, mode);

    //We may not return null directly
    return (scm == null) ? new NullSCM() : scm;
}

From source file:org.apache.oozie.workflow.lite.LiteWorkflowValidator.java

/**
 * This method recursively validates two things:
 * - fork/join methods are properly paired
 * - there are no multiple "okTo" paths to a given node
 *
 * Important: this method assumes that the workflow is not acyclic - therefore this must run after performBasicValidation()
 *
 * @param app The WorkflowApp//from   w w w .  j a v  a2 s  .c  om
 * @param node Current node we're checking
 * @param currentFork Current fork node (null if we are not under a fork path)
 * @param topDecisionParent The top (eldest) decision node along the path to this node, or null if there isn't one
 * @param okPath false if node (or an ancestor of node) was gotten to via an "error to" transition or via a join node that has
 * already been visited at least once before
 * @param forkJoins Map that contains a mapping of fork-join node pairs.
 * @param nodeAndDecisionParents Map that contains a mapping of nodes and their eldest decision node
 * @throws WorkflowException If there is any of the constraints described above is violated
 */
private void validateForkJoin(LiteWorkflowApp app, NodeDef node, NodeDef currentFork, String topDecisionParent,
        boolean okPath, Deque<String> path, Map<String, String> forkJoins,
        Map<String, Optional<String>> nodeAndDecisionParents) throws WorkflowException {
    final String nodeName = node.getName();

    path.addLast(nodeName);

    /* If we're walking an "okTo" path and the nodes are not Kill/Join/End, we have to make sure that only a single
     * "okTo" path exists to the current node.
     *
     * The "topDecisionParent" represents the eldest decision in the chain that we've gone through. For example, let's assume
     * that D1, D2, D3 are decision nodes and A is an action node.
     *
     * D1-->D2-->D3---> ... (rest of the WF)
     *  |   |    |
     *  |   |    |
     *  |   |    +----> +---+
     *  |   +---------> | A |
     *  +-------------> +---+
     *
     * In this case, there are three "okTo" paths to "A" but it's still a valid workflow because the eldest decision node
     * is D1 and during every run, there is only one possible execution path that leads to A (D1->A, D1->D2->A or
     * (D1->D2->D3->A). In the code, if we encounter a decision node and we already have one, we don't update it. If it's null
     * then we set it to the current decision node we're under.
     *
     * If the "current" and "top" parents are null, it means that we reached the node from two separate "okTo" paths, which is
     * not acceptable.
     *
     * Also, if we have two distinct top decision parents it means that the node is reachable from two decision paths which
     * are not "chained" (like in the example).
     *
     * It's worth noting that the last two examples can only occur in case of fork-join when we start to execute at least
     * two separate paths in parallel. Without fork-join, multiple parents or two null parents would mean that there is a loop
     * in the workflow but that should not happen since it has been validated.
     */
    if (okPath && !(node instanceof KillNodeDef) && !(node instanceof JoinNodeDef)
            && !(node instanceof EndNodeDef)) {
        // using Optional here so we can distinguish between "non-visited" and "visited - no parent" state.
        Optional<String> decisionParentOpt = nodeAndDecisionParents.get(nodeName);
        if (decisionParentOpt == null) {
            nodeAndDecisionParents.put(node.getName(), Optional.fromNullable(topDecisionParent));
        } else {
            String decisionParent = decisionParentOpt.isPresent() ? decisionParentOpt.get() : null;

            if ((decisionParent == null && topDecisionParent == null)
                    || !Objects.equal(decisionParent, topDecisionParent)) {
                throw new WorkflowException(ErrorCode.E0743, nodeName);
            }
        }
    }

    /* Fork-Join validation logic:
     *
     * At each Fork node, we recurse to every possible paths, changing the "currentFork" variable to the Fork node. We stop
     * walking as soon as we encounter a Join node. At the Join node, we update the forkJoin mapping, which maintains
     * the relationship between every fork-join pair (actually it's join->fork mapping). We check whether the join->fork
     * mapping already contains another Fork node, which means that the Join is reachable from at least two distinct
     * Fork nodes, so we terminate the validation.
     *
     * From the Join node, we don't recurse further. Therefore, all recursive calls return back to the point where we called
     * validateForkJoin() from the Fork node in question.
     *
     * At this point, we have to check how many different Join nodes we've found at each different paths. We collect them to
     * a set, then we make sure that we have only a single Join node for all Fork paths. Otherwise the workflow is broken.
     *
     * If we have only a single Join, then we get the transition node from the Join and go on with the recursive validation -
     * this time we use the original "currentFork" variable that we have on the stack. With this approach, nested
     * Fork-Joins are handled correctly.
     */
    if (node instanceof ForkNodeDef) {
        final List<String> transitions = node.getTransitions();

        checkForkTransitions(app, transitions, node);

        for (String t : transitions) {
            NodeDef transition = app.getNode(t);
            validateForkJoin(app, transition, node, topDecisionParent, okPath, path, forkJoins,
                    nodeAndDecisionParents);
        }

        // get the Join node for this ForkNode & validate it (we must have only one)
        Set<String> joins = new HashSet<String>();
        collectJoins(app, forkJoins, nodeName, joins);
        checkJoins(joins, nodeName);

        List<String> joinTransitions = app.getNode(joins.iterator().next()).getTransitions();
        NodeDef next = app.getNode(joinTransitions.get(0));

        validateForkJoin(app, next, currentFork, topDecisionParent, okPath, path, forkJoins,
                nodeAndDecisionParents);
    } else if (node instanceof JoinNodeDef) {
        if (currentFork == null) {
            throw new WorkflowException(ErrorCode.E0742, node.getName());
        }

        // join --> fork mapping
        String forkNode = forkJoins.get(nodeName);
        if (forkNode == null) {
            forkJoins.put(nodeName, currentFork.getName());
        } else if (!forkNode.equals(currentFork.getName())) {
            throw new WorkflowException(ErrorCode.E0758, node.getName(), forkNode + "," + currentFork);
        }
    } else if (node instanceof DecisionNodeDef) {
        List<String> transitions = node.getTransitions();

        // see explanation above - if we already have a topDecisionParent, we don't update it
        String parentDecisionNode = topDecisionParent;
        if (parentDecisionNode == null) {
            parentDecisionNode = nodeName;
        }

        for (String t : transitions) {
            NodeDef transition = app.getNode(t);
            validateForkJoin(app, transition, currentFork, parentDecisionNode, okPath, path, forkJoins,
                    nodeAndDecisionParents);
        }
    } else if (node instanceof KillNodeDef) {
        // no op
    } else if (node instanceof EndNodeDef) {
        // We can't end the WF if we're on a Fork path. From the "path" deque, we remove the last node (which
        // is the current "End") and look at last node again so we know where we came from
        if (currentFork != null) {
            path.removeLast();
            String previous = path.peekLast();
            throw new WorkflowException(ErrorCode.E0737, previous, node.getName());
        }
    } else if (node instanceof ActionNodeDef) {
        String transition = node.getTransitions().get(0); // "ok to" transition
        NodeDef okNode = app.getNode(transition);
        validateForkJoin(app, okNode, currentFork, topDecisionParent, true, path, forkJoins,
                nodeAndDecisionParents);

        transition = node.getTransitions().get(1); // "error to" transition
        NodeDef errorNode = app.getNode(transition);
        validateForkJoin(app, errorNode, currentFork, topDecisionParent, false, path, forkJoins,
                nodeAndDecisionParents);
    } else if (node instanceof StartNodeDef) {
        String transition = node.getTransitions().get(0); // start always has only 1 transition
        NodeDef tranNode = app.getNode(transition);
        validateForkJoin(app, tranNode, currentFork, topDecisionParent, okPath, path, forkJoins,
                nodeAndDecisionParents);
    } else {
        throw new WorkflowException(ErrorCode.E0740, node.getClass());
    }

    path.remove(nodeName);
}

From source file:org.apache.tajo.engine.planner.global.ParallelExecutionQueue.java

@Override
public synchronized ExecutionBlock[] first() {
    int max = Math.min(maximum, executable.size());
    List<ExecutionBlock> result = new ArrayList<>();
    for (Deque<ExecutionBlock> queue : executable) {
        if (result.size() < max && isExecutableNow(queue.peekLast())) {
            result.add(queue.removeLast());
        }/*from  ww w.ja  va2 s . c  o m*/
    }
    LOG.info("Initial executable blocks " + result);
    return result.toArray(new ExecutionBlock[result.size()]);
}

From source file:org.apache.tajo.engine.planner.global.ParallelExecutionQueue.java

@Override
public synchronized ExecutionBlock[] next(ExecutionBlockId doneNow) {
    executed.add(doneNow);/*from   w  ww .j  a  va  2  s  .c  om*/

    int remaining = 0;
    for (Deque<ExecutionBlock> queue : executable) {
        if (!queue.isEmpty() && isExecutableNow(queue.peekLast())) {
            LOG.info("Next executable block " + queue.peekLast());
            return new ExecutionBlock[] { queue.removeLast() };
        }
        remaining += queue.size();
    }
    return remaining > 0 ? new ExecutionBlock[0] : null;
}

From source file:org.openconcerto.sql.view.list.UpdateQueue.java

protected void willPut(final Runnable qr) throws InterruptedException {
    if (qr instanceof ChangeAllRunnable) {
        // si on met tout  jour, ne sert  rien de garder les maj prcdentes.
        // ATTN aux runnables qui dpendent des update, si on enlve les maj
        // elles vont s'executer sans que sa maj soit faite
        this.tasksDo(new IClosure<Deque<FutureTask<?>>>() {
            @Override//from  w ww  . j  a v a  2 s . c  om
            public void executeChecked(final Deque<FutureTask<?>> tasks) {
                // on part de la fin et on supprime toutes les maj jusqu'a ce qu'on trouve
                // un runnable qui n'est pas un UpdateRunnable
                FutureTask<?> current = tasks.peekLast();
                boolean onlyUpdateRunnable = true;
                while (current != null && onlyUpdateRunnable) {
                    onlyUpdateRunnable = isCancelableUpdate(current);
                    if (onlyUpdateRunnable) {
                        tasks.removeLast();
                        current = tasks.peekLast();
                    }
                }
                if (onlyUpdateRunnable) {
                    final FutureTask<?> br = getBeingRun();
                    if (br != null && isCancelableUpdate(br))
                        br.cancel(true);
                }
            }
        });
    }
}