private boolean unloadRegions(boolean unloadFromRack, List<String> isolateRegionIdArray)
    throws InterruptedException, ExecutionException, TimeoutException {
    deleteFile(this.filename);
    ExecutorService unloadPool = Executors.newFixedThreadPool(1);
    Future<Boolean> unloadTask = unloadPool.submit(() -> {
      List<RegionInfo> movedRegions = Collections.synchronizedList(new ArrayList<>());
      try {
        // Get Online RegionServers
        List<ServerName> regionServers = new ArrayList<>();
        RSGroupInfo rsgroup = admin.getRSGroup(Address.fromParts(hostname, port));
        LOG.info("{} belongs to {}", hostname, rsgroup.getName());
        regionServers.addAll(filterRSGroupServers(rsgroup, admin.getRegionServers()));
        // Remove the host Region server from target Region Servers list
        ServerName server = stripServer(regionServers, hostname, port);
        if (server == null) {
          LOG.info("Could not find server '{}:{}' in the set of region servers. giving up.",
            hostname, port);
          LOG.debug("List of region servers: {}", regionServers);
          return false;
        }
        // Remove RS not present in the designated file
        includeExcludeRegionServers(designatedFile, regionServers, true);

        // Remove RS present in the exclude file
        includeExcludeRegionServers(excludeFile, regionServers, false);

        if (unloadFromRack) {
          // remove regionServers that belong to same rack (as source host) since the goal is to
          // unload regions from source regionServer to destination regionServers
          // that belong to different rack only.
          String sourceRack = rackManager.getRack(server);
          List<String> racks = rackManager.getRack(regionServers);
          Iterator<ServerName> iterator = regionServers.iterator();
          int i = 0;
          while (iterator.hasNext()) {
            iterator.next();
            if (racks.size() > i && racks.get(i) != null && racks.get(i).equals(sourceRack)) {
              iterator.remove();
            }
            i++;
          }
        }

        // Remove decommissioned RS
        Set<ServerName> decommissionedRS = new HashSet<>(admin.listDecommissionedRegionServers());
        if (CollectionUtils.isNotEmpty(decommissionedRS)) {
          regionServers.removeIf(decommissionedRS::contains);
          LOG.debug("Excluded RegionServers from unloading regions to because they "
            + "are marked as decommissioned. Servers: {}", decommissionedRS);
        }

        stripMaster(regionServers);
        if (regionServers.isEmpty()) {
          LOG.warn("No Regions were moved - no servers available");
          return false;
        } else {
          LOG.info("Available servers {}", regionServers);
        }
        unloadRegions(server, regionServers, movedRegions, isolateRegionIdArray);
      } catch (Exception e) {
        LOG.error("Error while unloading regions ", e);
        return false;
      } finally {
        if (movedRegions != null) {
          writeFile(filename, movedRegions);
        }
      }
      return true;
    });
    return waitTaskToFinish(unloadPool, unloadTask, "unloading");
  }
Isolated regions specified in {@link #isolateRegionIdArray} on {@link #hostname} in ack Mode
and Unload regions from given {@link #hostname} using ack/noAck mode and {@link #maxthreads}.
In noAck mode we do not make sure that region is successfully online on the target region
server,hence it is the best effort. We do not unload regions to hostnames given in
{@link #excludeFile}. If designatedFile is present with some contents, we will unload regions
to hostnames provided in {@link #designatedFile}
@return true if region isolation succeeded, false otherwise
hbase-server/src/main/java/org/apache/hadoop/hbase/util/RegionMover.java