public void run() {

        // start the drones
        for (Drone drone : drones.values()) {

            System.out.println(String.format("Sending initial destinations to drone %d", drone.getDroneId()));

            while (drone.addDestination(_droneLocations.get(drone.getDroneId()).get(0))) {
                _droneLocations.get(drone.getDroneId()).remove(0);
            }
            drone.setName("" + drone.getDroneId());
            drone.start();
        }

        long t0 = System.nanoTime();
        long t1 = t0;
        while (_time.isBefore(LocalTime.of(8, 10))) {  // end simulation at 8:10
            if (t1 - t0 >= Program.SampleInterval) {

                readWriteLock.writeLock().lock();
                _time = _time.plusSeconds((t1 - t0) / Program.SampleInterval);
                readWriteLock.writeLock().unlock();

                for (Drone d : drones.values()) {
                    if (!_droneLocations.get(d.getDroneId()).isEmpty()) {
                        if (d.addDestination(_droneLocations.get(d.getDroneId()).get(0))) {
                            _droneLocations.get(d.getDroneId()).remove(0);
                        }
                    } else {
                        System.out.println(String.format("Dispatcher have no more destinations for drone %d", d.getDroneId()));
                    }
                }
                t0 = System.nanoTime();
            }
            t1 = System.nanoTime();
        }

        System.out.println(String.format("Shutting down at %s", _time));

        // terminate drones
        for (Drone drone : drones.values()) {
            drone.terminate("SHUTDOWN");
        }
    }