Pregunta

No soy un buen programador de Java, es sólo mi hobby, pero estoy ansioso por saber más de las cosas de la media.

Quiero resolver un problema matemático con múltiples hilos en Java. mi problema de matemáticas se puede separar en unidades de trabajo, que quiero haber resuelto en varios temas.

pero no quiere tener una cantidad fija de hilos que trabajan en él, pero en lugar de una cantidad coresponding de hilos a la cantidad de núcleos de CPU. y mi problema es que no pude encontrar un tutorial fácil en el Internet para esto. todo lo que encontré son ejemplos con hilos fijos.

Entonces, ¿podría ayudarme con un enlace a una buena tuturial o me podía dar un ejemplo sencillo y bueno? Eso sería muy agradable:)

¿Fue útil?

Solución

Se puede determinar el número de procesos disponibles para la máquina virtual de Java utilizando el método de ejecución estática, availableProcessors . Una vez que haya determinado el número de procesadores disponibles, cree que el número de hilos y dividir su trabajo en consecuencia.

Actualizar : Para aclarar aún más, un hilo es sólo un objeto en Java, por lo que se puede crear al igual que crearía cualquier otro objeto. Por lo tanto, digamos que se llama al método anterior y encontrar que devuelve 2 procesadores. Increíble. Ahora, puede crear un bucle que genera un nuevo hilo, y divide el trabajo fuera de ese hilo, y los incendios fuera de la rosca. He aquí algunos 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, cabeza para este tutorial . Además, es posible que desee ver en Thread Pooling para la creación de los hilos.

Otros consejos

Es probable que desee ver en el marco java.util.concurrent para estas cosas también. Algo así 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

Este es un bonito montón de hacer frente a sus propios grupos de subprocesos etc.

Doug Lea (autor del paquete concurrente) tiene este documento que pueden ser pertinentes: http://gee.cs.oswego.edu/dl/papers/fj.pdf

El Tenedor de Ingreso marco se ha añadido a Java SE 7. A continuación se presentan algunos más referencias:

http://www.ibm.com/developerworks/ java / library / j-jtp11137 / index.html Artículo de Brian Goetz

http://www.oracle.com/technetwork/ artículos / java / tenedor-join-422606.html

Opción 1:

newWorkStealingPool desde Executors

public static ExecutorService newWorkStealingPool()
  

Crea una agrupación de hebras de robar el trabajo a utilizar todos los procesadores disponibles como su nivel de paralelismo objetivo.

Con esta API, no es necesario pasar el número de núcleos de ExecutorService.

La aplicación de esta API de 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);
    }

Opción 2:

newFixedThreadPool API de Executors o other newXXX constructors, que devuelve ExecutorService

public static ExecutorService newFixedThreadPool(int nThreads)

reemplazar con nThreads Runtime.getRuntime().availableProcessors()

Opción 3:

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                      int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue)

pasar Runtime.getRuntime().availableProcessors() como parámetro para maximumPoolSize.

La forma estándar es la Runtime.getRuntime (). AvailableProcessors método (). En la mayoría de las CPUs estándar se le ha devuelto el número de hilos óptima (que no es el recuento real núcleo de la CPU) aquí. Por lo tanto esto es lo que busca.

Ejemplo:

ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

No se olvide de cerrar el servicio ejecutor como éste (o su programa no saldrá):

service.shutdown();

A continuación, sólo un esbozo rápido cómo configurar un código basado MT futuro (offtopic, por ejemplo):

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)));
    }

Luego hay que realizar un seguimiento de la cantidad de resultados que usted espera y recuperarlos como esto:

try {
  int received = 0;
  while (received < elementsToCompute.size()) {
     Future<YourCallableImplementor> resultFuture = completionService.take(); 
     YourCallableImplementor result = resultFuture.get();
     received++; 
  }
} finally {
  service.shutdown();
}

En la clase de tiempo de ejecución, hay un método llamado availableProcessors (). Puede usarlo para averiguar cuántas CPU que tiene. Debido a que su programa está obligado CPU, es probable que desee tener (como máximo) un hilo por la CPU disponible.

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