¿Hay alguna diferencia de rendimiento entre AtomicInteger
y Integer
?Diferencia de rendimiento de AtomicInteger vs Integer
Respuesta
La elección de estos dos tipos no debe depender del rendimiento. La elección principal para AtomicInteger
es si desea lograr seguridad de hilo con las operaciones en el entero.
Sin embargo, la diferencia de rendimiento puede depender en gran medida del sistema operativo elegido, ya que la implementación detallada de las operaciones atómicas depende del sistema operativo.
+1. AtomicInteger también proporciona un entero mutable barato, incluso en un caso de uso no simultáneo. –
-1: AtomicInteger existe principalmente por razones de rendimiento (para implementar estructuras de datos sin bloqueo). Si la seguridad era la única preocupación, simplemente podría usar la sincronización. –
@MichaelBorgwardt: el hecho de que la seguridad de las hebras sea posible con solo la sincronización no significa que AtomicInteger no proporcione operaciones enteras seguras para subprocesos. El punto de la respuesta es que el rendimiento bruto de Integer y AtomicInteger no es lo que guía la elección de uno u otro. Lo que guía la elección es el uso previsto: ¿necesitamos un entero mutable seguro para subprocesos, o simplemente queremos convertir un número entero en un objeto inmutable? –
Aparte de la sobrecarga de sincronización muy pequeña, no.
Bueno, si lo usa en entornos multiproceso, como, por ej. mostrador, entonces usted tiene que synchronize
acceso al entero
public final class Counter {
private long value = 0;
public synchronized long getValue() {
return value;
}
public synchronized long increment() {
return ++value;
}
}
Mientras que usted puede tener un rendimiento mucho mejor con AtomicInteger sin sincronización
public class NonblockingCounter {
private AtomicInteger value;
public int getValue() {
return value.get();
}
public int increment() {
return value.incrementAndGet();
}
}
Lecturas recomendadas http://cephas.net/blog/2006/09/06/atomicinteger/
EDITAR uso incrementAndGet
¿Por qué no usar incrementAndGet? –
te refieres a [getAndIncrement] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#getAndIncrement())? Bueno, buena pregunta, señor, creo que fui demasiado rápido y flojo. – bpgergo
No, me refiero a incrementAndGet. getAndIncrement sería equivalente a devolver i ++. Pero tu primer fragmento vuelve +++; –
AtomicInteger
permite algunos (¡no todas!) operaciones que de otro modo requerirían que la sincronización se realizara sin bloqueos usando instrucciones de hardware especiales. Cómo esto afecta el rendimiento es un tanto complejo:
- En primer lugar, se trata de una micro-optimización que solo importará si esta operación en particular está en la ruta crítica de su aplicación.
- Las instrucciones especiales de hardware pueden no estar disponibles en plataformas no convencionales, en cuyo caso
AtomicInteger
probablemente se implementará mediante la sincronización. - La JVM a menudo puede optimizar los gastos generales de bloqueo cuando no hay contención (por ejemplo, una sola aplicación de subprocesos). En ese caso, probablemente no haya diferencia.
- Si hay un conflicto de bloqueo de bajo a moderado (es decir, varios subprocesos, pero en su mayoría hacen otras cosas además de simplemente acceder a ese entero), el algoritmo sin bloqueo funciona mejor que la sincronización.
- Si hay una contención de bloqueo muy pesada (es decir, muchos subprocesos que pasan mucho tiempo tratando de acceder a ese entero), la sincronización puede funcionar mejor porque el algoritmo de bloqueo se basa en reintentar constantemente la operación cuando falla debido a una colision.
Exactamente los tipos de hechos que he estado buscando. Gracias. –
encontré con este anuncio de hoy, pero quería compartir mis resultados (Por favor, no hay comentarios en código como que tenía a mano escriba las siguientes clases como el sistema me encontré con éste en que no estaba conectado a internet :)
línea inferior la salida del código de abajo fue el siguiente:
resultadosatómico: transcurrido = 25257 ms, ExpectedValue = 50.000, FinalValue = 50000, verdaderos resultados primitiva: transcurrido = 25257 ms, ExpectedValue = 50.000, FinalValue = 48991, falso
Para mi uso en mi aplicación particular, he elegido usar valores atómicos para los números de estado en una clase de monitoreo.En caso de que alguien más quisiera ver algunos resultados difíciles, opté por publicar esta información.
¡Que tengas un gran día!
Clases:
he creado una clase principal con una larga primitivo y un atómicas métodos de incremento de longitud y de descriptor de acceso, un IncrementAtomicRunnable y un IncrementPrimitiveRunnable.
LongOverhead:
public class LongOverhead{
AtomicLong atomicLong;
long primitiveLong;
public LongOverhead(){
atomicLong = new AtomicLong(0l);
primitiveLong = 0l;
}
public void incrAtomicLong(){
atomicLong.getAndAdd(1l);
}
public long getAtomicLong(){
return atomicLong.get();
}
public void incrPrimitiveLong(){
primitiveLong++;
}
public long getPrimitiveLong(){
return primitiveLong;
}
public static void main(String [] args){
String template = "%s Results: Elapsed = %d ms, ExpectedValue = %d, FinalValue = %d, %b";
int loopTotal = 1000;
int waitMilliseconds = 25;
int totalThreads = 50;
int expectedValue = loopTotal * totalThreads;
int whileSleep = 250;
LongOverhead atomic = new LongOverhead();
LongOverhead primitive = new LongOverhead();
List<Thread> atomicThreads = new ArrayList<>();
List<Thread> primitiveThreads = new ArrayList<>();
for(int x=0;x<totalThreads;x++){
Thread a = new Thread(new IncrementalAtomicRunnable(atomic, loopTotal, waitMilliseconds), "AtomicIncr" + x);
atomicThreads.add(a);
Thread p = new Thread(new IncrementalPrimitiveRunnable(primitive, loopTotal, waitMilliseconds), "PrimitiveIncr" + x);
primitiveThreads.add(p);
}
boolean cont = true;
long atomicStart = System.currentTimeMillis();
for(Thread t: atomicThreads){
t.start();
}
while(cont){
try{
Thread.sleep(whileSleep);
}catch(InterruptedException e){
e.printStackTrace();
}
boolean foundAlive = false;
for(Thread t: atomicThreads){
foundAlive = (State.TERMINATED != t.getState());
if(foundAlive){
break;
}
}
cont = foundAlive;
}
long atomicFinish = System.currentTimeMillis();
long atomicElapsed = atomicFinish - atomicStart;
long atomicFinal = atomic.getAtomicLong();
cont = true;
long primitiveStart = System.currentTimeMillis();
for(Thread t: primitiveThreads){
t.start();
}
while(cont){
try{
Thread.sleep(whileSleep);
}catch(InterruptedException e){
e.printStackTrace();
}
boolean foundAlive = false;
for(Thread t: primitiveThreads){
foundAlive = (State.TERMINATED != t.getState());
if(foundAlive){
break;
}
}
cont = foundAlive;
long primitiveFinish = System.currentTimeMillis();
long primitiveElapsed = primitiveFinish - primitiveStart;
long primitiveFinal = primitive.getPrimitiveLong();
System.out.println(String.format(template, "ATOMIC", atomicElapsed, expectedValue, atomicFinal, (expectedValue==atomicFinal)));
System.out.println(String.format(template, "PrImItIvE", primitiveElapsed, expectedValue, primitiveFinal, (expectedValue==primitiveFinal)));
}
IncrementAtomicRunnable:
public class IncrementAtomicRunnable implements Runnable{
protected LongOverhead oh;
protected int loopTotal;
protected int waitMilliseconds;
protected String currentThreadName;
public IncrementAtomicRunnable(LongOverhead oh, int loopTotal, int waitMilliseconds){
this.oh = oh;
this.loopTotal = loopTotal;
this.waitMilliseconds = waitMilliseconds;
}
@Override
public void run(){
currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " for ATOMIC is starting.....");
for(int x=0;x<loopTotal;x++){
oh.incrAtomicLong();
try{
Thread.sleep(waitMilliseconds);
}catch(InterruptedException e){
System.out.println("InterruptedThread[" + currentThreadName + "], eating exception @@@@@");
}
}
System.out.println("....." + currentThreadName + " for ATOMIC is finished.");
}
}
y finalmente IncrementPrimitiveRunnable:
public class IncrementPrimitiveRunnable extends IncrementAtomicRunnable{
public IncrmentPrimitiveRunnable(LongOverhead oh, int loopTotal, int waitMilliseconds){
super(oh, loopTotal, waitMilliseconds);
}
@Override
public void run(){
super.currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " for PRIMITIVE is starting.....");
for(int x=0;x<loopTotal;x++){
oh.incrPrimitiveLong();
try{
Thread.sleep(waitMilliseconds);
}catch(InterruptedException e){
System.out.println("InterruptedThread[" + currentThreadName + "], eating exception @@@@@");
}
}
System.out.println("....." + currentThreadName + " for PRIMITIVE is finished.");
}
}
- 1. AtomicIntegerArray vs AtomicInteger []
- 2. AtomicInteger lazySet vs. set
- 3. AtomicInteger vs getters/setters sincronizados
- 4. JRuby vs rendimiento de YARV --- ¿diferencia notable?
- 5. Uninitialized int vs Integer
- 6. Usando int vs Integer
- 7. Incremento de AtomicInteger
- 8. return String vs Integer vs undefined vs null
- 9. ¿Por qué AtomicInteger implementa Serializable
- 10. Rendimiento - Date.now() vs date.getTime()
- 11. rendimiento de adaptIntegrate vs. integrar
- 12. RenderAction vs RenderPartial rendimiento
- 13. JavaScript - === vs == operadores rendimiento
- 14. Usar con vs declarar una tabla temporal: rendimiento/diferencia?
- 15. tipo vs rendimiento de datos en haskell
- 16. Rendimiento de UIView: removeFromSuperview VS hide
- 17. Rendimiento de ReceiveAsync vs. BeginReceive
- 18. Rendimiento de XPath vs DOM
- 19. Estrategia de registro vs. rendimiento
- 20. Genéricos vs Objeto de rendimiento
- 21. .NET boxeo/unboxing vs rendimiento de conversión
- 22. Rendimiento de GridView vs DataList vs Repeater vs ListView
- 23. AtomicInteger para generación de secuencia limitada
- 24. rendimiento D: Unión vs @property
- 25. erlang vs jvm (scala) rendimiento de recursión
- 26. Método de extensión de rendimiento vs. Método de instancia
- 27. nchar vs nvarchar rendimiento
- 28. CSV vs MySQL rendimiento
- 29. git vs mercurial rendimiento
- 30. SimpleXML vs DOMDocument rendimiento
Mídalo si le interesa. – artbristol