<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def download_data(request_list, redownload=False, max_threads=None):
 """ Download all requested data or read data from disk, if already downloaded and available and redownload is not required. :param request_list: list of DownloadRequests :type request_list: list of DownloadRequests :param redownload: if ``True``, download again the data, although it was already downloaded and is available on the disk. Default is ``False``. :type redownload: bool :param max_threads: number of threads to use when downloading data; default is ``max_threads=None`` which by default uses the number of processors on the system :type max_threads: int :return: list of Futures holding downloaded data, where each element in the list corresponds to an element in the download request list. :rtype: list[concurrent.futures.Future] """

    _check_if_must_download(request_list, redownload)

    LOGGER.debug("Using max_threads=%s for %s requests", max_threads, len(request_list))

    with concurrent.futures.ThreadPoolExecutor(max_workers=max_threads) as executor:
        return [executor.submit(execute_download_request, request) for request in request_list]