protected void updateComputerList(final boolean automaticSlaveLaunch) {
        final Map<Node,Computer> computers = getComputerMap();
        final Set<Computer> old = new HashSet<Computer>(computers.size());
        Queue.withLock(new Runnable() {
            @Override
            public void run() {
                Map<String,Computer> byName = new HashMap<String,Computer>();
                for (Computer c : computers.values()) {
                    old.add(c);
                    Node node = c.getNode();
                    if (node == null)
                        continue;   // this computer is gone
                    byName.put(node.getNodeName(),c);
                }

                Set<Computer> used = new HashSet<>(old.size());

                updateComputer(AbstractCIBase.this, byName, used, automaticSlaveLaunch);
                for (Node s : getNodes()) {
                    long start = System.currentTimeMillis();
                    updateComputer(s, byName, used, automaticSlaveLaunch);
                    if (LOG_STARTUP_PERFORMANCE && LOGGER.isLoggable(Level.FINE)) {
                        LOGGER.fine(String.format("Took %dms to update node %s",
                                System.currentTimeMillis() - start, s.getNodeName()));
                    }
                }

                // find out what computers are removed, and kill off all executors.
                // when all executors exit, it will be removed from the computers map.
                // so don't remove too quickly
                old.removeAll(used);
                // we need to start the process of reducing the executors on all computers as distinct
                // from the killing action which should not excessively use the Queue lock.
                for (Computer c : old) {
                    c.inflictMortalWound();
                }
            }
        });
        for (Computer c : old) {
            // when we get to here, the number of executors should be zero so this call should not need the Queue.lock
            killComputer(c);
        }
        getQueue().scheduleMaintenance();
        for (ComputerListener cl : ComputerListener.all()) {
            try {
                cl.onConfigurationChange();
            } catch (Throwable t) {
                LOGGER.log(Level.WARNING, null, t);
            }
        }
    }
protected void updateComputerList ( final boolean automaticSlaveLaunch ) { final Map < Node , Computer > computers = getComputerMap ( ) ; final Set < Computer > old = new HashSet < Computer > ( computers . size ( ) ) ; Queue . withLock ( new Runnable ( ) { @ Override public void run ( ) { Map < String , Computer > byName = new HashMap < String , Computer > ( ) ; for ( Computer c : computers . values ( ) ) { old . add ( c ) ; Node node = c . getNode ( ) ; if ( node == null ) continue ; byName . put ( node . getNodeName ( ) , c ) ; } Set < Computer > used = new HashSet < > ( old . size ( ) ) ; updateComputer ( AbstractCIBase . this , byName , used , automaticSlaveLaunch ) ; for ( Node s : getNodes ( ) ) { long start = System . currentTimeMillis ( ) ; updateComputer ( s , byName , used , automaticSlaveLaunch ) ; if ( LOG_STARTUP_PERFORMANCE && LOGGER . isLoggable ( Level . FINE ) ) { LOGGER . fine ( String . format ( "Took %dms to update node %s" , System . currentTimeMillis ( ) - start , s . getNodeName ( ) ) ) ; } } old . removeAll ( used ) ; for ( Computer c : old ) { c . inflictMortalWound ( ) ; } } } ) ; for ( Computer c : old ) { killComputer ( c ) ; } getQueue ( ) . scheduleMaintenance ( ) ; for ( ComputerListener cl : ComputerListener . all ( ) ) { try { cl . onConfigurationChange ( ) ; } catch ( Throwable t ) { LOGGER . log ( Level . WARNING , null , t ) ; } } }
Updates Computers.

<p>
This method tries to reuse existing {@link Computer} objects
so that we won't upset {@link Executor}s running in it.