Domanda

Non sono un buon programmatore java, è solo il mio hobby, ma io sono ansioso di sapere più di roba media.

Voglio risolvere un problema matematico con più thread in Java. il mio problema di matematica può essere suddivisa in unità di lavoro, che voglio aver risolto in diversi thread.

ma io non voglio avere un importo fisso di fili che lavorano su di esso, ma invece una quantità di fili coresponding alla quantità di core della CPU. e il mio problema è che non riuscivo a trovare un tutorial facile in internet per questo. complesso ho trovato sono esempi con fili fissi.

Quindi, mi potrebbe aiutare con un link ad un buon tuturial o mi potrebbe dare un esempio semplice e buono? Sarebbe davvero bello:)

È stato utile?

Soluzione

È possibile determinare il numero di processi a disposizione del Java Virtual Machine utilizzando il metodo Runtime statico, availableProcessors . Una volta determinato il numero di processori disponibili, creare quel numero di thread e dividere il vostro lavoro di conseguenza.

Aggiorna : Per chiarire ulteriormente, un thread è solo un oggetto in Java, quindi è possibile crearlo proprio come si farebbe creare qualsiasi altro oggetto. Quindi, diciamo che si chiama il metodo di cui sopra e scoprire che restituisce 2 processori. Eccezionale. Ora, è possibile creare un ciclo che genera un nuovo thread, e divide il lavoro off per quel filo, e spara fuori il filo. Ecco alcuni psuedocodarlo per dimostrare quello che voglio dire:

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

Per ulteriori informazioni su come creare un filo, a questo tutorial . Inoltre, si consiglia di guardare Pooling discussione per la creazione dei fili.

Altri suggerimenti

Probabilmente si desidera guardare il quadro java.util.concurrent per questa roba troppo. Qualcosa di simile:

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

Questo è molto più bello di far fronte con i propri pool di thread, ecc.

Doug Lea (autore del pacchetto concorrente) ha questa carta che possono essere rilevanti: http://gee.cs.oswego.edu/dl/papers/fj.pdf

Il Fork Join quadro è stato aggiunto alla Java SE 7. Qui di seguito sono alcuni più riferimenti:

http://www.ibm.com/developerworks/ java / library / j-jtp11137 / index.html Articolo di Brian Goetz

http://www.oracle.com/technetwork/ articoli / java / fork-join-422606.html

Opzione 1:

newWorkStealingPool da Executors

public static ExecutorService newWorkStealingPool()
  

Crea un pool di thread di lavoro furto utilizzando tutti i processori disponibili come suo livello obiettivo parallelismo.

Con questa API, non è necessario passare numero di core per ExecutorService.

L'attuazione di questa API da 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);
    }

Opzione 2:

newFixedThreadPool API da Executors o other newXXX constructors, che restituisce ExecutorService

public static ExecutorService newFixedThreadPool(int nThreads)

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

Opzione 3:

ThreadPoolExecutor

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

Runtime.getRuntime().availableProcessors() passaggio come parametro per maximumPoolSize.

Il modo standard è il Runtime.getRuntime (). Metodo availableProcessors (). Sulla maggior CPU standard si avrà restituito il numero di thread ottimale (che non è il reale numero di core CPU) qui. Quindi questo è quello che stai cercando.

Esempio:

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

Non dimenticare di disattivare il servizio esecutore come questo (o il vostro programma non uscirà):

service.shutdown();

Ecco solo un rapido contorno come impostare un codice di MT basato futuro (offtopic, per l'illustrazione):

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

Allora avete bisogno di tenere traccia di quante i risultati che ci si aspetta e recuperarli in questo modo:

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

In classe Runtime, c'è un metodo chiamato availableProcessors (). È possibile utilizzare che per capire quante CPU che hai. Dal momento che il programma è destinato CPU, si sarebbe probabilmente desidera avere (al massimo) un thread per CPU disponibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top