Pregunta

Parece haber mucho alboroto sobre multinúcleo y Java.Si bien algunas personas dicen que el soporte de Java no es suficientemente bueno, definitivamente parece ser un área que esperamos con ansias.Parece ser muchos técnicas para mejorar el rendimiento de programas concurrentes.

Se agradece cualquier sugerencia/consejo sobre programación en un escenario multinúcleo.

¿Fue útil?

Solución

Mire las nuevas funciones de concurrencia de Java (en el java.util.concurrent paquete) que se han agregado en Java 5.Proporciona una funcionalidad de más alto nivel que la normal. Threads que hará que sea más fácil (y menos propenso a errores) escribir aplicaciones simultáneas.El Lección:concurrencia de Los tutoriales de Java Sería un buen punto de partida.

Hasta ahora sólo he usado el ExecutorService, lo que permite producir grupos de hilos, a los que se pueden traspasar nuevas tareas en unidades de Runnables o Callables (que puede devolver valores después de la ejecución como Futures), y el código de subprocesamiento real es manejado por el ExecutorService.

Por ejemplo, realizar algún cálculo utilizando un grupo de subprocesos de 2 subprocesos y obtener el resultado puede ser tan simple como:

ExecutorService es = Executors.newFixedThreadPool(2);

Future f1 = es.submit(new Callable<Integer>() {
    public Integer call()
    {
        // Do some processing...
        return someInteger;
    }
});

Future f2 = es.submit(new Callable<Integer>() {
    public Integer call()
    {
        // Do some processing...
        return someInteger;
    }
});

Integer firstInteger = f1.get();
Integer secondInteger = f2.get();

En el código anterior (no probado), lo único de lo que tengo que preocuparme es de hacer un par de Callablearena submitenviándolo al ExecutorService y más adelante, utilizando el Futures para recuperar el resultado.

El problema es que, una vez que get método de la Future se llama, si el procesamiento no se completa, el programa se detendrá hasta que se obtenga el resultado del Future se puede recuperar.Entonces, en este ejemplo, incluso si el resultado de f2 está disponible antes f1, el programa esperará hasta el resultado de f1 está disponible.

En términos de material de lectura, en mi lista de libros para comprar próximamente está Concurrencia de Java en la práctica por Brian Goetz, que aparece a menudo cuando se menciona la concurrencia en Java.

El Utilidades de concurrencia La página de la documentación de Java 5 también tiene más información.

Otros consejos

El mejor consejo tiene que ser: ¡obtenga su sincronización correcta!

Esto puede parecer algo obvio, pero una comprensión del Java Memory Model es vital, particularmente cómo funcionan los campos volátil y final , cómo sincronizado actúa como mutex y una barrera de memoria y luego las nuevas java.util.concurrent construcciones también

Siempre es un buen consejo: si la mayoría de sus clases son inmutables, todo se vuelve mucho más fácil ya que la inmutabilidad elimina la necesidad de preocuparse por las cerraduras de muchos a pocos lugares de interés.

Mira el próximo marco de unión en horquilla.El marco fork-join permite a los desarrolladores lograr un paralelismo detallado en arquitecturas multinúcleo.

También es posible que desee consultar los lenguajes basados ​​en JVM como Clojure que pretenden facilitar la programación paralela multinúcleo.

Como alternativa al enfoque de concurrencia de memoria compartida de Java, también puede consultar Concurrencia basada en actores usando Scala sobre Java, que proporciona un modelo más fácil para la programación concurrente.

Vea la charla de Brian Goetz De concurrente a Paralelo de Devoxx 2008. No hay muchos consejos allí, pero le da una idea de hacia dónde se dirige la concurrencia de Java.

Puede intentar usar una biblioteca de patrones de paralelismo como Skandium para Java. Simplemente elija el patrón de paralelismo que desee y complete los ganchos que faltan.

Algunos de los patrones soportados en Skandium son:

  • Maestro-esclavo: Farm<P,R>(nested);
  • Pipeline: `Pipe (etapa1, etapa2);
  • Para iteración: For<P,R>(nested, i);
  • iteración condicional: While<P,R>(nested, condition);
  • Ramificación condicional: If<P,R>(condition, trueCase, falseCase);
  • Reducción de mapa: Map<P,R>(split, nested, merge);
  • Map-reduce con diferentes rutas de código: Fork<P,R>(split, nested, merge);
  • Divide y vencerás recursivamente: DaC<P,R>(condition, split, nested, merge);

Todos los patrones se pueden anidar y combinar, para que pueda tener una granja dentro de una división y conquista, etc.

El mejor libro con consejos prácticos ha sido Concurrencia de Java en la práctica . Es una lectura obligada para todos los programadores de Java, incluso aquellos que piensan que no hacen ninguna programación concurrente, porque Java tiene muchos subprocesos ocultos en sus diversas bibliotecas (el swing viene a la mente, lo mismo con los servlets).

Mi consejo: Comprenda el modelo de memoria Java (desde JDK 5 y superior). La mayoría de las personas no saben que la sincronización, la volátil y la final tienen un significado adicional más allá del alcance normal de subprocesos múltiples.

Java está bien para multi-cpu y multi-núcleos. Si lo programa correctamente e invierte algo de cerebro, obtendrá un sistema de servidor altamente concurrente para utilizar 8 núcleos, incluida una gran cantidad de sincronización, etc. Estamos bastante contentos con eso ... JDK6 es mejor que JDK5 y todo lo que se muestra a continuación apesta en máquinas con varias CPU.

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