Pular para o conteúdo
Bruno Dórea
Todos os posts

6 mins de leitura


Processamento Paralelo/Assíncrono - Tempo de Download Paralelo

Explorando Padrões de Projetos com Kotlin - 5/5


Desenvolvimento Backend com Kotlin
Desenvolvimento Backend com Kotlin

Descrição

No mundo da programação, frequentemente enfrentamos situações onde múltiplas tarefas precisam ser executadas simultaneamente para otimizar o tempo de resposta ou processamento. Um exemplo comum é o download de múltiplos arquivos da internet.

Para este desafio, suponha que você tenha uma lista de URLs que deseja "baixar". Seu objetivo é simular o download desses arquivos de forma paralela e imprimir o tamanho de cada URL após seu "download" ter sido disparado. Para simplificar, cada URL leva exatamente 1 segundo para ser "baixado".

Requisitos:

  1. Defina uma lista de URLs que você deseja "baixar".
  2. Crie uma função para simular o "download" de uma URL. Essa função deve aceitar uma URL como entrada e retornar o tamanho da URL.
  3. Implemente uma lógica que permita iniciar o "download" de várias URLs em paralelo.
  4. Imprima o tamanho de cada URL na ordem em que foram inseridas.

Entrada

A entrada consiste em uma lista de URLs, uma em cada linha. Uma linha vazia indica o fim da lista.

Saída

A saída deve mostrar o tamanho de cada URL na ordem em que foram inseridas, seguido pelo "Tempo total", que é simplesmente a contagem de URLs (por mais conta-intuitivo que pareça 😁): Iniciando downloads... Arq1: $tamanhoUrl1 Arq2: $tamanhoUrl2 Tempo total: $quantidadeDeUrls

Exemplos

A tabela abaixo apresenta exemplos com alguns dados de entrada e suas respectivas saídas esperadas. Certifique-se de testar seu programa com esses exemplos e com outros casos possíveis.

EntradaSaída
https://chat.openai.com/Iniciando downloads...
https://www.invertexto.com/Arq1: 24
https://web.dio.me/Arq2: 27
[Linha vazia]Arq3: 19
Tempo total: 3
EntradaSaída
https://www.netflix.com/Iniciando downloads...
https://www.hbomax.com/Arq1: 24
https://www.amazon.com.br/Arq2: 23
[Linha vazia]Arq3: 26
Tempo total: 3
EntradaSaída
https://refactoring.guru/Iniciando downloads...
https://github.com/Arq1: 25
https://stackoverflow.com/Arq2: 19
[Linha vazia]Arq3: 26
Tempo total: 3

Resolução

import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
 
fun main() {
    val urls = mutableListOf<String>()
 
    while (true) {
        val input = readLine() ?: break
        if (input.isBlank()) break
        urls.add(input)
    }
 
    println("Iniciando downloads...")
 
    val executor = Executors.newFixedThreadPool(urls.size)
    val results = mutableListOf<Pair<Int, Int>>()
 
    urls.forEachIndexed { index, url ->
        executor.submit {
            val length = simulateDownload(url)
            synchronized(results) {
                results.add(Pair(index, length))
            }
        }
    }
 
    executor.shutdown()
    executor.awaitTermination(1, TimeUnit.MINUTES)
 
    results.sortedBy { it.first }.forEachIndexed { idx, result ->
        println("Arq${idx + 1}: ${result.second}")
    }
    println("Tempo total: ${urls.size}")
}
 
fun simulateDownload(url: String): Int {
    Thread.sleep(1000)
    return url.length
}

Para encontrar outras soluções, verifique aqui.

Caso encontre algum erro ou tenha sugestões, clique aqui e abra uma issue no Github.