Объединение потоков выполнить краткий

Если вы разрабатываете программы, которые выполняют много недолгих задачи, то будет целесообразно воспользоваться техникой называемый опрос потоков. Вместо того чтобы создать поток для каждой новой задачи и отбрасывая поток, когда задача выполнена, вы можете создать пул потоков и дать бассейном каждую задачу выполнить. Если поток в бассейне имеется, задача выполняется немедленно. Thread возвращается в купальню, когда задача выполнена. В противном случае, задача ждет потока стала доступна из бассейна, прежде чем выполнить.

J2SE 5.0 предлагает новый пакет java.util.concurrent, и в этом пакете существует параллелизм утилиты, которые предоставляют встроенных Пул потоков рамки. Интерфейса Исполнителя в java.util.concurrent обеспечивает единый метод Execute, который принимает работающий объект следующим образом:


   public interface Executor {

     public void execute(Runnable command);

   }

Для использования потока рамках объединения, необходимо создать экземпляр Исполнителю, то вы передаете его Runnable Некоторые задачи:


   Executor executor = ...;

   executor.execute(aRunnable1);

   executor.execute(aRunnable2);

Затем вы создаете или найти реализацию интерфейса Исполнителя. Осуществление могло бы выполнить задачу немедленно, в новую тему или последовательно. Например, вот это реализация, что порождает новый поток для каждой задачи:


   class MyExecutor implements Executor {

       public void execute(Runnable r) {

           new Thread(r).start();

       }

   }

Параллелизм утилитами также включать класс ThreadPoolExecutor, который предлагает поддержку для многих общих объединения операций. С одной из четырех конструкторов ThreadPoolExecutor, вы можете указать параметры, такие как размер пула, оставьте в живых время, поток завода, а обработчик отклонил темы:


   public ThreadPoolExecutor(int corePoolSize,

                             int maximumPoolSize,

                             long keepAliveTime,

                             TimeUnit unit,

                             BlockingQueue<Runnable> workQueue)



   public ThreadPoolExecutor(int corePoolSize,

                             int maximumPoolSize,

                             long keepAliveTime,

                             TimeUnit unit,

                             BlockingQueue<Runnable> workQueue,

                             ThreadFactory threadFactory)



   public ThreadPoolExecutor(int corePoolSize,

                             int maximumPoolSize,

                             long keepAliveTime,

                             TimeUnit unit,

                             BlockingQueue<Runnable> workQueue,

                             RejectedExecutionHandler handler)



   public ThreadPoolExecutor(int corePoolSize,

                             int maximumPoolSize,

                             long keepAliveTime,

                             TimeUnit unit,

                             BlockingQueue<Runnable> workQueue,

                             ThreadFactory threadFactory,

                             RejectedExecutionHandler handler)

Но вы действительно не должны вызвать конструктор. Вместо этого, исполнители классом java.util.concurrent пакет создает пул потоков для вас. В простейшем случае, вы вызываете newFixedThreadPool метод в класс исполнителей и перейти в число потоков вы хотите в бассейне. Затем Вы используете ExecutorService, интерфейс, который расширяет Исполнителя, либо выполнить Runnable задач или представлять их. Вызов метода представляет ExecutorService позволяет получить обратно результат. Представить метод также возвращает будущего объекта, который можно использовать, чтобы проверить, если задача выполнена.

Давайте запустим тестовую программу для демонстрации использования пулов потоков. Во-первых, вот программа, NamePrinter, который уведомляет вас, когда она начинается, паузы для некоторого количества времени, и уведомляет вас, когда это делается.


   public class NamePrinter implements Runnable {

     private final String name;

     private final int delay;

     public NamePrinter(String name, int delay) {

       this.name = name;

       this.delay = delay;

     }

     public void run() {

       System.out.println("Starting: " + name);

       try {

         Thread.sleep(delay);

       catch (InterruptedException ignored) {

       }

       System.out.println("Done with: " + name);

     }

   }

Вот тестовая программа, UsePool. Он создает поток бассейна размером 3, и добавляет, 10 задач, он (то есть 10 рейсов NamePrinter). Программа UsePool затем ждет задач завершить до вызова и выключения awaitTermination. ExecutorService следует выключения перед прекращено. Существует также shutdownNow метода, который пытается немедленное выключение. Прекращение здесь даже быстрее, чем через закрытие методом. ShutdownNow метод возвращает список всех оставшихся Runnable задач.


   import java.util.concurrent.*;

   import java.util.Random;

   

   

   public class UsePool {

     public static void main(String args[]) {

       Random random = new Random();

       ExecutorService executor = 

               Executors.newFixedThreadPool(3);

       // Sum up wait times to know when to shutdown

       int waitTime = 500;

       for (int i=0; i<10; i++) {

         String name = "NamePrinter " + i;

         int time = random.nextInt(1000);

         waitTime += time;

         Runnable runner = new NamePrinter(name, time);

         System.out.println("Adding: " + name + " / " + time);

         executor.execute(runner);

       }

       try {

         Thread.sleep(waitTime);

         executor.shutdown();

         executor.awaitTermination

                 (waitTime, TimeUnit.MILLISECONDS);

       catch (InterruptedException ignored) {

       }

       System.exit(0);

     }

    }

Обобщение NamePrinter и UsePool, затем запустите UsePool. Вот пример вывода запуска — отмечают, что при каждом запуске будет уникальным со случайными спит по настоящее время:

Adding: NamePrinter 0 / 30
Adding: NamePrinter 1 / 727
Adding: NamePrinter 2 / 980
Starting: NamePrinter 0
Starting: NamePrinter 1
Starting: NamePrinter 2
Adding: NamePrinter 3 / 409
Adding: NamePrinter 4 / 49
Adding: NamePrinter 5 / 802
Adding: NamePrinter 6 / 211
Adding: NamePrinter 7 / 459
Adding: NamePrinter 8 / 994
Adding: NamePrinter 9 / 459
Done with: NamePrinter 0
Starting: NamePrinter 3
Done with: NamePrinter 3
Starting: NamePrinter 4
Done with: NamePrinter 4
Starting: NamePrinter 5
Done with: NamePrinter 1
Starting: NamePrinter 6
Done with: NamePrinter 6
Starting: NamePrinter 7
Done with: NamePrinter 2
Starting: NamePrinter 8
Done with: NamePrinter 5
Starting: NamePrinter 9
Done with: NamePrinter 7
Done with: NamePrinter 9
Done with: NamePrinter 8

Обратите внимание, что первые три NamePrinter объекты начали быстро. Позже NamePrinter объектах начались как каждый исполнитель NamePrinter объект закончен.

Существует гораздо больше для объединения потоков рамках имеющихся в J2SE 5.0. Например, вы можете создать запланирована пулы потоков, где вы можете планировать задачи выполнить "позже".

Более подробную информацию о потоках объединения и новых утилит параллелизм, см. Concurrency утилиты.

Copyright (C) 2004-2005 Sun Microsystems, Inc
Все права защищены.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>