El uso de bloqueos cuando no lo necesite ralentizará su aplicación. Podría ser demasiado pequeño para medir o podría ser sorprendentemente alto.
En mi humilde opinión, la mejor opción es utilizar el código de bloqueo en un único programa de subprocesos para dejar en claro que este código no está destinado a ser compartido a través de subprocesos. Esto podría ser más importante para el mantenimiento que cualquier problema de rendimiento.
public static void main(String... args) throws IOException {
for (int i = 0; i < 3; i++) {
perfTest(new Vector<Integer>());
perfTest(new ArrayList<Integer>());
}
}
private static void perfTest(List<Integer> objects) {
long start = System.nanoTime();
final int runs = 100000000;
for (int i = 0; i < runs; i += 20) {
// add items.
for (int j = 0; j < 20; j+=2)
objects.add(i);
// remove from the end.
while (!objects.isEmpty())
objects.remove(objects.size() - 1);
}
long time = System.nanoTime() - start;
System.out.printf("%s each add/remove took an average of %.1f ns%n", objects.getClass().getSimpleName(), (double) time/runs);
}
impresiones
Vector each add/remove took an average of 38.9 ns
ArrayList each add/remove took an average of 6.4 ns
Vector each add/remove took an average of 10.5 ns
ArrayList each add/remove took an average of 6.2 ns
Vector each add/remove took an average of 10.4 ns
ArrayList each add/remove took an average of 5.7 ns
Desde el punto de vista del rendimiento, si 4 ns es importante para usted, usted tiene que utilizar la versión no sincronizada.
Para el 99% de los casos de uso, la claridad del código es más importante que el rendimiento. El código claro y simple a menudo funciona razonablemente bien también.
BTW: Estoy usando un i7 2600 a 4.6 GHz con Oracle Java 7u1.
Para la comparación si hago lo siguiente donde perfTest1,2,3 son idénticos.
perfTest1(new ArrayList<Integer>());
perfTest2(new Vector<Integer>());
perfTest3(Collections.synchronizedList(new ArrayList<Integer>()));
me sale
ArrayList each add/remove took an average of 2.6 ns
Vector each add/remove took an average of 7.5 ns
SynchronizedRandomAccessList each add/remove took an average of 8.9 ns
Si utilizo un método común perfTest
no puede inline el código de la forma más óptima y todos ellos son lentos
ArrayList each add/remove took an average of 9.3 ns
Vector each add/remove took an average of 12.4 ns
SynchronizedRandomAccessList each add/remove took an average of 13.9 ns
Intercambiar el orden de las pruebas
ArrayList each add/remove took an average of 3.0 ns
Vector each add/remove took an average of 39.7 ns
ArrayList each add/remove took an average of 2.0 ns
Vector each add/remove took an average of 4.6 ns
ArrayList each add/remove took an average of 2.3 ns
Vector each add/remove took an average of 4.5 ns
ArrayList each add/remove took an average of 2.3 ns
Vector each add/remove took an average of 4.4 ns
ArrayList each add/remove took an average of 2.4 ns
Vector each add/remove took an average of 4.6 ns
uno a la vez
ArrayList each add/remove took an average of 3.0 ns
ArrayList each add/remove took an average of 3.0 ns
ArrayList each add/remove took an average of 2.3 ns
ArrayList each add/remove took an average of 2.2 ns
ArrayList each add/remove took an average of 2.4 ns
y
Vector each add/remove took an average of 28.4 ns
Vector each add/remove took an average of 37.4 ns
Vector each add/remove took an average of 7.6 ns
Vector each add/remove took an average of 7.6 ns
Vector each add/remove took an average of 7.6 ns
Niza en que esta disposición es, las cosas han evolucionado mucho ** ** ya que fue escrito hace diez años. – NPE
respuesta corta: ¡sí! – bestsss
Respuesta larga: sí. La JVM siempre tendrá que resolver si la clave del objeto está disponible, independientemente de la evolución de Java. –