Questão de Programação — Plataforma Java — FUNDATEC 2026
Programação›Plataforma Java
Código
qg686030
Banca
FUNDATEC
Órgão
IFC-SC
Ano
2026
Nível
Superior
Cargo
Professor EBTT - Informática: Programação de Sistemas
Analise o seguinte programa em Java SE 11:Considerando a execução concorrente das threads e o funcionamento da instrução valor++. E, ainda, que a JVM pode intercalar as operações das threads de forma imprevisível e que a operação de incremento (valor++) não é atômica na especificação Java, assinale a alternativa correta.
AO uso de join() garante que não haverá interferência entre as threads.
BO programa sempre imprimirá 1000, pois apenas uma thread executa por vez.
CO programa não compila, pois múltiplas threads não podem acessar a mesma variável.
DO programa sempre imprimirá exatamente 2000, pois cada thread incrementa o contador mil vezes.
EO programa pode imprimir um valor menor que 2000, devido a condições de corrida durante a execução concorrente.
Revelar gabarito e comentário▾
GabaritoE — O programa pode imprimir um valor menor que 2000, devido a condições de corrida durante a execução concorrente.
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”.
Concorrência em Java: a não atomicidade do valor++
Gabarito: letra E. O programa pode imprimir um valor menor que 2000 porque a operação valor++ não é atômica na especificação Java — ela é composta por três passos (ler, incrementar, escrever) e, quando duas threads executam essa sequência de forma intercalada, uma atualização pode ser sobrescrita pela outra, caracterizando uma condição de corrida (race condition). O enunciado já adianta o ponto central: a JVM pode intercalar as operações de forma imprevisível e o incremento não é atômico.
A condição de corrida é o fenômeno que ocorre quando duas ou mais threads acessam um mesmo recurso compartilhado sem sincronização, e o resultado final depende da ordem imprevisível de execução. No caso do valor++, a operação não é uma única instrução atômica: ela envolve, na prática, três passos — ler o valor atual da variável, somar 1 a esse valor e escrever o resultado de volta na memória. Se duas threads executam esses passos de forma intercalada, pode acontecer o seguinte: a thread A lê o valor 100, a thread B também lê o valor 100, ambas incrementam para 101 e ambas escrevem 101 — ou seja, duas operações de incremento resultaram em apenas um incremento efetivo. Esse é o cenário clássico de perda de atualização (lost update).
Imagine duas threads, T1 e T2, cada uma executando valor++ uma única vez, partindo de valor = 0. Se a execução for sequencial (T1 completa antes de T2 começar), o resultado é 2. Mas se houver intercalação — T1 lê 0, T2 lê 0, T1 escreve 1, T2 escreve 1 — o resultado final é 1, e não 2. No programa da questão, cada thread executa o incremento mil vezes, então o valor máximo possível é 2000, mas qualquer intercalação que cause perda de atualização reduz o resultado final. Por isso, o programa pode imprimir um valor menor que 2000 — e nunca maior, pois o incremento só aumenta o valor.
A solução para esse problema é a sincronização. Em Java, as formas mais comuns são: o uso da palavra-chave synchronized em um bloco ou método, que garante que apenas uma thread execute a seção crítica por vez; o uso de classes atômicas como AtomicInteger, cujo método incrementAndGet() é atômico; ou o uso de Lock explícito da API java.util.concurrent. O método join(), mencionado na alternativa A, não resolve o problema: ele apenas faz a thread que o chama aguardar a conclusão da thread alvo, mas não impede que as duas threads executem simultaneamente antes do join — a interferência já terá ocorrido.
A pegadinha desta questão é justamente a intuição de que, como cada thread incrementa mil vezes, o total deveria ser 2000. Essa intuição ignora a não atomicidade do ++ e a possibilidade de intercalação. A banca explora exatamente essa confusão entre o comportamento esperado em execução sequencial e o comportamento real em execução concorrente. Guarde a fronteira: sem sincronização, operações não atômicas sobre variáveis compartilhadas produzem resultados imprevisíveis — é esse o critério que separa as alternativas.
1Ler valor atual
2Somar 1
3Escrever de volta
LEVEL · soulevel.com.br
Alternativa A — ❌ Incorreta
O join() não garante ausência de interferência. Ele apenas faz a thread chamadora esperar a conclusão da thread alvo. No programa, se a thread principal chama join() em ambas as threads, isso garante que o programa só imprima o valor após as duas terminarem — mas não impede que as duas executem simultaneamente e interfiram uma na outra durante a execução. A interferência (condição de corrida) ocorre durante a execução concorrente, e o join() não a previne.
Alternativa B — ❌ Incorreta
O programa não imprime sempre 1000. O valor máximo possível é 2000, pois cada uma das duas threads incrementa o contador mil vezes. O valor 1000 seria o resultado se apenas uma thread executasse, ou se houvesse uma perda massiva de atualizações — mas não é um valor garantido. A afirmação de que "apenas uma thread executa por vez" é falsa: as threads executam concorrentemente, e é justamente essa concorrência que causa o problema.
Alternativa C — ❌ Incorreta
O programa compila normalmente. Múltiplas threads podem acessar a mesma variável em Java — isso é permitido pela linguagem. O que ocorre é que, sem sincronização, o acesso concorrente a uma variável compartilhada pode gerar resultados incorretos, mas não um erro de compilação. A compilação verifica sintaxe e tipos, não questões de concorrência.
Alternativa D — ❌ Incorreta
O programa não imprime sempre exatamente 2000. Embora cada thread execute o incremento mil vezes, a não atomicidade do valor++ permite que atualizações sejam perdidas quando as threads intercalam suas operações. O valor 2000 só seria garantido se o incremento fosse atômico ou se houvesse sincronização — o que não é o caso. O resultado pode ser qualquer valor entre 1000 (no pior caso, se todas as operações de uma thread forem perdidas) e 2000.
Alternativa E — ✅ Correta ⟵ GABARITO
Esta é a única alternativa que reflete corretamente o comportamento do programa. A operação valor++ não é atômica: ela envolve ler, incrementar e escrever. Quando duas threads executam essa sequência de forma intercalada, uma atualização pode ser sobrescrita pela outra, resultando em um valor final menor que 2000. O enunciado já afirma que a JVM pode intercalar as operações de forma imprevisível e que o incremento não é atômico — exatamente o que caracteriza a condição de corrida. O programa pode imprimir um valor menor que 2000, e essa é a resposta correta.
NÃO CAIA NESSA!
A banca explora a intuição de que "duas threads × mil incrementos = 2000". Essa conta só vale se o incremento fosse atômico ou se houvesse sincronização. Como valor++ é uma operação composta (ler, somar, escrever), a intercalação entre threads pode fazer com que dois incrementos resultem em apenas um — e o total final fica abaixo de 2000. Fique atento: sempre que uma questão mencionar "não atômico" e "intercalação", a resposta envolve condição de corrida e resultado imprevisível.
PEGA ESSA DICA!
Para resolver questões de concorrência, identifique se a operação sobre a variável compartilhada é atômica. Se não for (como ++, --, ou qualquer operação de ler-modificar-escrever), o resultado é imprevisível sem sincronização. As soluções em Java são: synchronized, AtomicInteger (com incrementAndGet()), ou Lock. O join() apenas aguarda a conclusão das threads — não sincroniza o acesso à variável.