termino - multihilos java
Java: ¿Cómo escalar hilos de acuerdo con núcleos de CPU? (6)
No soy un buen programador de Java, es solo mi hobby, pero estoy ansioso por saber algo más que lo normal.
Quiero resolver un problema matemático con múltiples hilos en java. mi problema matemático se puede separar en unidades de trabajo, que quiero haber resuelto en varios hilos.
pero no quiero tener una cantidad fija de subprocesos trabajando en ello, sino una cantidad correspondiente de subprocesos para la cantidad de núcleos de CPU. y mi problema es que no pude encontrar un tutorial fácil en Internet para esto. todo lo que encontré son ejemplos con hilos fijos.
Entonces, ¿podría ayudarme con un enlace a un buen tuturial o podría darme un ejemplo fácil y bueno? Eso sería realmente agradable :)
Doug Lea (autor del paquete simultáneo) tiene este documento que puede ser relevante: http://gee.cs.oswego.edu/dl/papers/fj.pdf
El marco Fork Join se ha agregado a Java SE 7. A continuación se incluyen algunas referencias más:
http://www.ibm.com/developerworks/java/library/j-jtp11137/index.html Artículo de Brian Goetz
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
En la clase Runtime, hay un método llamado availableProcessors (). Puedes usar eso para calcular cuántas CPU tienes. Dado que su programa está vinculado a la CPU, es probable que desee tener (como máximo) un hilo por CPU disponible.
La forma estándar es el método Runtime.getRuntime (). AvailableProcessors (). En la mayoría de las CPU estándar, habrá devuelto el recuento de subprocesos óptimo (que no es el recuento de núcleos de CPU) aquí. Por lo tanto, esto es lo que estás buscando.
Ejemplo:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
NO se olvide de cerrar el servicio ejecutor de esta manera (o su programa no se cerrará):
service.shutdown();
Aquí solo un breve resumen de cómo configurar un futuro código de MT basado (offtopic, para ilustración):
CompletionService<YourCallableImplementor> completionService =
new ExecutorCompletionService<YourCallableImplementor>(service);
ArrayList<Future<YourCallableImplementor>> futures = new ArrayList<Future<YourCallableImplementor>>();
for (String computeMe : elementsToCompute) {
futures.add(completionService.submit(new YourCallableImplementor(computeMe)));
}
Entonces necesita realizar un seguimiento de cuántos resultados espera y recuperarlos así:
try {
int received = 0;
while (received < elementsToCompute.size()) {
Future<YourCallableImplementor> resultFuture = completionService.take();
YourCallableImplementor result = resultFuture.get();
received++;
}
} finally {
service.shutdown();
}
Probablemente también desee ver el marco java.util.concurrent para este material. Algo como:
ExecutorService e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// Do work using something like either
e.execute(new Runnable() {
public void run() {
// do one task
}
});
o
Future<String> future = pool.submit(new Callable<String>() {
public String call() throws Exception {
return null;
}
});
future.get(); // Will block till result available
Esto es mucho mejor que lidiar con tus propios grupos de hilos, etc.
Puede determinar la cantidad de procesos disponibles para la Máquina Virtual Java utilizando el método Runtime estático, availableProcessors . Una vez que haya determinado la cantidad de procesadores disponibles, cree esa cantidad de hilos y divida su trabajo según corresponda.
Actualización : para aclarar aún más, un subproceso es solo un objeto en Java, por lo que puede crearlo tal como lo haría con cualquier otro objeto. Entonces, digamos que llamas al método anterior y encuentras que devuelve 2 procesadores. Increíble. Ahora puede crear un bucle que genere un nuevo subproceso y divida el trabajo para ese subproceso y desconecte el subproceso. Aquí hay un psuedocode para demostrar lo que quiero decir:
int processors = Runtime.getRuntime().availableProcessors();
for(int i=0; i < processors; i++) {
Thread yourThread = new AThreadYouCreated();
// You may need to pass in parameters depending on what work you are doing and how you setup your thread.
yourThread.start();
}
Para obtener más información sobre cómo crear su propio hilo, diríjase a este tutorial . Además, es posible que desee consultar agrupamiento de subprocesos para la creación de los subprocesos.
Opción 1:
newWorkStealingPool de los Executors
public static ExecutorService newWorkStealingPool()
Crea un grupo de subprocesos de robo de trabajo utilizando todos los procesadores disponibles como su nivel de paralelismo de destino.
Con esta API, no necesita pasar la cantidad de núcleos a ExecutorService
.
Implementación de esta API desde grepcode
/**
* Creates a work-stealing thread pool using all
* {@link Runtime#availableProcessors available processors}
* as its target parallelism level.
* @return the newly created thread pool
* @see #newWorkStealingPool(int)
* @since 1.8
*/
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
Opcion 2:
newFixedThreadPool API de los Executors
u other newXXX constructors
, que devuelve ExecutorService
public static ExecutorService newFixedThreadPool(int nThreads)
reemplace nThreads con Runtime.getRuntime().availableProcessors()
Opción 3:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
pase Runtime.getRuntime().availableProcessors()
como parámetro a maximumPoolSize
.