Question

Je ne suis pas un bon programmeur java, il est juste mon passe-temps, mais je suis impatient de connaître plus de choses moyenne.

Je veux résoudre un problème mathématique avec plusieurs threads en Java. mon problème mathématique peut être séparé en unités de travail, que je veux avoir résolu dans plusieurs threads.

mais je ne veux pas avoir un montant fixe de fils qui y travaillent, mais une quantité de fils pour lui correspondant la quantité de noyaux de cpu. et mon problème est que je ne pouvais pas trouver un tutoriel facile dans Internet pour cela. tout ce que je trouve des exemples avec des fils fixes.

Pourriez-vous me aider avec un lien vers une bonne tuturial ou pourrait me donner un moyen facile et bon exemple? Ce serait vraiment bien:)

Était-ce utile?

La solution

Vous pouvez déterminer le nombre de processus disponibles à la machine virtuelle Java en utilisant la méthode statique d'exécution, availableProcessors . Une fois que vous avez déterminé le nombre de processeurs disponibles, créer ce nombre de threads et de diviser votre travail en conséquence.

Mise à jour : Pour clarifier davantage, un thread est juste un objet en Java, donc vous pouvez le créer comme vous le feriez créer tout autre objet. Alors, disons que vous appelez la méthode ci-dessus et de trouver qu'il retourne 2 processeurs. Impressionnant. Maintenant, vous pouvez créer une boucle qui génère un nouveau thread, et divise le travail hors de ce fil, et le fil de feu. Voici quelques psuedocode pour démontrer ce que je veux 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();
}

Pour plus d'informations sur la création de votre propre fil, à ce tutoriel . En outre, vous voudrez peut-être regarder Pooling fil pour la création des fils.

Autres conseils

Vous voulez probablement regarder le cadre java.util.concurrent pour ce genre de choses aussi. Quelque chose comme:

ExecutorService e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// Do work using something like either
e.execute(new Runnable() {
        public void run() {
            // do one task
        }
    });

ou

    Future<String> future = pool.submit(new Callable<String>() {
        public String call() throws Exception {
            return null;
        }
    });
    future.get();  // Will block till result available

Ceci est beaucoup plus agréable que faire face à vos propres pools de threads, etc.

Option 1:

newWorkStealingPool de Executors

public static ExecutorService newWorkStealingPool()
  

Crée un pool de threads antivols travail en utilisant tous les processeurs disponibles comme son niveau de parallélisme cible.

Avec cette API, vous n'avez pas besoin de passer nombre de cœurs à ExecutorService.

La mise en œuvre de cette API 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);
    }

Option 2:

newFixedThreadPool API de Executors ou other newXXX constructors, qui retourne ExecutorService

public static ExecutorService newFixedThreadPool(int nThreads)

avec nThreads remplacer Runtime.getRuntime().availableProcessors()

Option 3:

ThreadPoolExecutor

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

Runtime.getRuntime().availableProcessors() passe en tant que paramètre à maximumPoolSize.

La méthode standard est la méthode Runtime.getRuntime (). AvailableProcessors de (). Sur la plupart des CPU standard, vous avez retourné le nombre de threads optimal (ce qui est le nombre de cœurs de CPU réelle) ici. Par conséquent, c'est ce que vous recherchez.

Exemple:

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

Ne pas oublier de fermer le service exécuteur comme celui-ci (ou votre programme ne quittera pas):

service.shutdown();

Voici juste un aperçu rapide comment mettre en place un code de futur basé MT (offtopic, à titre d'illustration):

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

Ensuite, vous devez garder une trace sur le nombre de résultats que vous attendez et les récupérer comme ceci:

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

Sur la classe d'exécution, il y a une méthode appelée availableProcessors (). Vous pouvez l'utiliser pour déterminer le nombre de processeurs que vous avez. Étant donné que votre programme est lié au CPU, vous voudrez probablement avoir (au plus) un thread par CPU disponible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top