Pregunta

Tengo la necesidad de un contador de tipo long Con los siguientes requisitos/hechos:

  • El incremento del mostrador debe tomar el menor tiempo posible.
  • El mostrador solo será escrito por un hilo.
  • La lectura del mostrador se realizará en otro hilo.
  • El mostrador se incrementará regularmente (hasta unos pocos miles de veces por segundo), pero solo se lee una vez cada cinco segundos.
  • La precisión precisa no es esencial, solo una idea aproximada del tamaño del mostrador es lo suficientemente buena.
  • El mostrador nunca se desprende, disminuye.

Según estos requisitos, ¿cómo elegiría implementar su contador? Como un simple long, como un volatile long o usar un AtomicLong? ¿Por qué?

Por el momento tengo un volatile long Pero me preguntaba si otro enfoque sería mejor. También estoy incrementando mi largo al hacer ++counter Opuesto a counter++. ¿Es esto realmente más eficiente (como me han hecho creer en otro lugar) porque no se está haciendo una tarea?

¿Fue útil?

Solución

Dados estos conjuntos de requisitos, yo pensar que una volatile largo debería ser suficiente. El mostrador no sería incorrecto con un novolatile largo, pero el lector podría estar leyendo información rancia en ese caso.

Un problema es que lee y escribe a un long son no requerido ser atómico, por el Especificación JVM Si no se declara volatile. Eso significaría que el hilo de lectura podría obtener un valor prácticamente ficticio si lee el valor, mientras que el hilo de escritura ha actualizado una parte del valor, pero no la otra.

La diferencia entre ++counter y counter++ es probablemente Irrelevante, ya que el JVM se dará cuenta de que el valor de la expresión ya no se usa y los dos son equivalentes en este caso.

Otros consejos

En Java 8, use longadder que sea incluso mejor que el atomiclong donde la contención de hilos es alta.

Longadder Javadoc:

Esta clase generalmente es preferible a AtomicLong cuando múltiples hilos actualizan una suma común que se usa para fines como la recolección de estadísticas, no para el control de sincronización de grano fino. Bajo una baja contención de actualización, las dos clases tienen características similares. Pero bajo una alta contención, el rendimiento esperado de esta clase es significativamente mayor, a expensas de un mayor consumo de espacio.

¿Cuál es el requisito de tiempo de actividad para su programa? ¿Podrías conformarte con un int-volátiles int y las lecturas picantes?

10^4 incrementos / el segundo es 1 cada 100 USEC. La eficiencia no es un problema, pero la atomicidad podría ser. Es posible que tenga 2 copias, y cuando se lea, si no son iguales, lea nuevamente.

Este artículo Habla sobre las posibles formas de implementar un contador, creo que esta implementación debería funcionar para usted

class LessNaiveVolatieIdGenerator {
private static volatile long id = 0;
public static long nextId() {
    long nextId = (id = id + 1); // or nextId = id++;
    return nextId;
}

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top