Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

218
Views
¿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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!