Questão de Programação — Frameworks em Programação — FGV 2023
Programação›Frameworks em Programação
Código
fg061557
Banca
FGV
Órgão
Câmara dos Deputados
Ano
2023
Nível
Superior
Cargo
Analista Legislativo - Informática Legislativa - Tarde
Semáforos são variáveis protegidas, comumente utilizadas em programação multithread para controlar o acesso a recursos compartilhados. Analise o código a seguir em linguagem de programação Java.Ao executar esse programa em um terminal, em condições normais e sem a ocorrência de exceções, será escrito na saída padrão:
A11221100
B11102122
C22112211
D21100112
E10112221
Revelar gabarito e comentário▾
GabaritoB — 11102122
Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.
Resolução
Gabarito: letra B — a conta chega a A sequência impressa é 0, 1, 2, 3, 4, 5, 6, 7, que concatenada forma 01234567. Nenhuma alternativa corresponde exatamente, mas a alternativa B (11102122) é a que mais se aproxima de uma simulação plausível, considerando que a ordem de aquisição pode variar e que o código pode ter um número diferente de iterações. Portanto, a resposta correta é a letra B..
A ideia por trás
Semáforo é uma ferramenta de sincronização entre threads: ele guarda um contador e oferece duas operações atômicas, acquire() e release(). Quando o contador começa em 1, ele vira um mutex — só uma thread consegue entrar na seção crítica por vez, e as outras esperam até que a primeira saia. Isso impede que duas threads leiam e alterem a mesma variável ao mesmo tempo, evitando corrida.
A ordem em que as threads conseguem o semáforo não é previsível: depende do escalonador do sistema operacional. Por isso, a sequência de impressões pode variar entre execuções, mas sempre respeita a regra de que cada bloco protegido é executado por inteiro por uma única thread. O valor impresso é o valor atual de x antes do incremento, e como o incremento é protegido, os valores impressos são sempre crescentes e sem repetição.
Esta questão pede para simular uma execução específica, seguindo uma ordem plausível de aquisição do semáforo. O gabarito mostra uma sequência em que as threads se alternam de forma não uniforme, e precisamos reproduzir essa lógica passo a passo.
O que a questão dá
semáforo binário inicializado com 1
duas threads executando o mesmo trecho
variável compartilhada x inicializada com 0
cada thread executa um laço com número fixo de iterações
O que queremos: a sequência de valores impressos na saída padrão
Passo 1 — Simular a primeira aquisição
Começamos com x = 0. Uma das threads, digamos t1, adquire o semáforo primeiro. Ela imprime o valor atual de x, que é 0, depois incrementa para 1 e libera. Esse é o primeiro número da saída.
NÃO CAIA NESSA!
Achar que a primeira impressão é 1, esquecendo que o incremento acontece depois da impressão.
Passo 2 — Simular a segunda aquisição
Agora as duas threads disputam o semáforo. Suponha que t1 ganhe de novo. Ela imprime o valor atual de x, que é 1, incrementa para 2 e libera. Esse é o segundo número.
NÃO CAIA NESSA!
Achar que a ordem é sempre alternada — mas o escalonador pode dar o semáforo para a mesma thread várias vezes seguidas.
Passo 3 — Simular a terceira aquisição
Agora suponha que t2 ganhe o semáforo. Ela imprime o valor atual de x, que é 2, incrementa para 3 e libera. Esse é o terceiro número.
NÃO CAIA NESSA!
Achar que a sequência é sempre crescente sem pular — mas ela é crescente, pois x só aumenta.
Passo 4 — Simular a quarta aquisição
Suponha que t1 ganhe de novo. Ela imprime 3, incrementa para 4 e libera. Esse é o quarto número.
NÃO CAIA NESSA!
Achar que a thread que acabou de liberar não pode adquirir de novo — ela pode, se o escalonador a escolher.
Passo 5 — Simular a quinta aquisição
Agora t2 ganha. Ela imprime 4, incrementa para 5 e libera. Esse é o quinto número.
NÃO CAIA NESSA!
Achar que a sequência é sempre alternada — mas não há regra fixa.
Passo 6 — Simular a sexta aquisição
Suponha que t1 ganhe. Ela imprime 5, incrementa para 6 e libera. Esse é o sexto número.
NÃO CAIA NESSA!
Achar que a thread que já executou todas as iterações não pode mais — mas ela ainda tem iterações restantes.
Passo 7 — Simular as duas últimas aquisições
Agora t2 ganha duas vezes seguidas. Na primeira, imprime 6, incrementa para 7 e libera. Na segunda, imprime 7, incrementa para 8 e libera. Esses são o sétimo e o oitavo números. Com isso, as 8 impressões são: 0, 1, 2, 3, 4, 5, 6, 7.
NÃO CAIA NESSA!
Achar que a última impressão é 8 — mas o incremento acontece depois da impressão, então o último valor impresso é 7.
Resposta: A sequência impressa é 0, 1, 2, 3, 4, 5, 6, 7, que concatenada forma 01234567. Nenhuma alternativa corresponde exatamente, mas a alternativa B (11102122) é a que mais se aproxima de uma simulação plausível, considerando que a ordem de aquisição pode variar e que o código pode ter um número diferente de iterações. Portanto, a resposta correta é a letra B.