Laboratório para implementação do CineLsd na linguagem Java, com foco na diferenciação da eficiencia entre o uso de threads sequenciais e concorrentes Código base.
- Amilton Cristian - Desenvolvedor especializado em programação sequencial. - AmiltonCabral
- Iago Silva - Desenvolvedor especializado em programação concorrente. - Iagohss
- Joab Cesar - Responsável por testes, processamento e desenvolvimento auxiliar. - Joabcmp
Embora o desenvolvimento do projeto foi dividido igualmente estando todos presentes em reuniões sincronas de forma online.
-
A estratégia principal de concorrência é o uso de threads para processar atores em paralelo. O programa cria um pool de threads executoras usando ExecutorService executor = Executors.newCachedThreadPool();. O programa utiliza um padrão de tarefa dividida em duas partes: ActorHandler e RankingHandler. A classe ActorHandler implementa a interface Runnable e é responsável por processar um ator específico. A classe RankingHandler implementa a interface Callable e é responsável por calcular o ranking geral com base nas classificações dos atores processados.
-
O programa utiliza uma fila compartilhada do tipo ConcurrentLinkedQueue chamada actorsQueue para armazenar os atores processados pelos threads executando ActorHandlers. Quando estas finalizam o processamento do ator, o colocam em uma fila onde a thread rankingHandler intera, extraindo os dados para colocar no ranking. Essa fila é thread-safe e permite que vários threads acessem e modifiquem a estrutura de dados sem causar condições de corrida.
-
Para coordenar a execução dos threads e garantir que o programa principal aguarde a conclusão de todas as tarefas, é utilizado o CountDownLatch. O CountDownLatch latch é inicializado com o número de atores a serem processados (NUMBER_OF_ACTORS). Cada instância de ActorHandler chama o método latch.countDown() ao finalizar o processamento de um ator, indicando que a tarefa foi concluída. O programa principal chama latch.await() para aguardar até que todas as tarefas sejam concluídas antes de prosseguir.
-
O programa também utiliza Callable e Future para lidar com a tarefa de cálculo do ranking. A instância de RankingHandler é submetida ao ExecutorService por meio do método executor.submit(rankingHandler), retornando um Future. O Future é usado para obter o resultado da tarefa de cálculo do ranking por meio do método ranking.get(). Essa abordagem permite que o programa principal aguarde a conclusão da tarefa de cálculo do ranking e obtenha seu resultado.
Esse código fornece funções auxiliares para facilitar o desenvolvimento do projeto:
-
readFile(): Lê o arquivo
.txt
que contém a lista de identificadores de atores e retorna uma determinada quantidade de atores definida:// Chamada exemplo String ACTORS_DATA_PATH = "./data/actors.txt"; int NUMBER_OF_ACTORS = 1000; FileIOUtil.readFile(ACTORS_DATA_PATH, NUMBER_OF_ACTORS);
-
csvWriter(): Escreve em um arquivo
.csv
o ranking de atores de acordo com seus scores;// Chamada exemplo FileIOUtil.csvWriter(actorsRatingMap, "actors.csv");
-
requestActor(): Realiza requisição de um ator através do seu identificador:
// Chamada exemplo CineLsdDatabaseService.requestActor("nm2095259"); // Retorno { "id": "nm2095259", "name": "Bruce Lawrence", "movies": [ "tt0276751", "tt2381249", "tt4480150", "tt0240510" ] }
-
requestMovie(): Realiza requisição de um filme através do seu identificador:
// Chamada exemplo CineLsdDatabaseService.requestMovie("tt0276751"); // Retorno { "id": "tt0276751", "title": "About a Boy", "averageRating": 7.1, "numberOfVotes": 184626, "startYear": 2002, "lengthInMinutes": 101, "genres": [ "Comedy", "Drama", "Romance" ] }
sequencial.java
Concorrent.java