Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

227
Visualizações
¿Cada ciclo de un bucle for es una operación atómica?

¿Es el método incrementAndGet de la siguiente implementación AtomicBigInteger una operación atómica? Me pregunto particularmente sobre la parte for (; ; ) . ¿La JVM garantiza de alguna manera que cada ciclo en un bucle for se ejecute atómicamente?

 public final class AtomicBigInteger { private final AtomicReference<BigInteger> valueHolder = new AtomicReference<>(); public AtomicBigInteger(BigInteger bigInteger) { valueHolder.set(bigInteger); } public BigInteger incrementAndGet() { for (; ; ) { BigInteger current = valueHolder.get(); BigInteger next = current.add(BigInteger.ONE); if (valueHolder.compareAndSet(current, next)) { return next; } } } }

Obtuve este código de aquí: ¿Es posible incrementar BigInteger de manera segura de una manera segura para subprocesos, tal vez con AtomicReference, sin bloqueo? Sin embargo, esta implementación estaba dando vueltas y puede encontrarla en muchos lugares diferentes en Internet.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

No, no es atómico, pero si otro subproceso ha modificado AtomicReference, entonces la llamada compareAndSet fallará y volverá a repetirse, obtendrá el valor, lo incrementará e intentará configurarlo nuevamente. Tarde o temprano (probablemente) tendrá éxito y actualizará el BigInteger en poder de AtomicReference al siguiente número.

over 4 years ago · Santiago Trujillo Relatório

0

El método incrementAndGet en su clase no será atómico. Este es el por qué.

Las clases Atomic* utilizan referencias de valores volatile . La compensación de memoria a estos valores también se mantiene dentro de las instancias mediante las cuales pueden buscar-incrementar-comparar-establecer en bucle hasta que el subproceso actual pueda realizar todas las operaciones de una sola vez (es decir, sin que otro subproceso realice un incremento en Entre).

Esto es posible para estos Atomic* , como veo, debido al acceso que tienen las clases "confiables" intrínsecas a las implementaciones no Unsafe . Las implementaciones no Unsafe tienen métodos para comparar y configurar atómicamente usando funciones native .

En casos como el que has mencionado, tendremos que recurrir a usar bloques synchronized , sus implementaciones equivalentes basadas en Lock o simplemente usar los métodos en AtomicReference . Me gusta esto:

 public class AtomicBigInteger{ private final AtomicReference<BigInteger> valueHolder = new AtomicReference<>(); public AtomicBigInteger(BigInteger bigInteger) { valueHolder.set(bigInteger); } public BigInteger incrementAndGet() { return valueHolder.updateAndGet( bigInt -> bigInt.add( BigInteger.ONE ) ); } }

Sin embargo, dado que estamos tratando con BigInteger , esta implementación también deberá revisarse porque la cantidad de iteraciones que AtomicReference.updateAndGet(..) puede tener que realizar puede ser significativa, porque BigInteger.add( BigInteger ) implica muchos pasos , a diferencia de una suma de dos int s.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda