2014-12-15 2 views
1

Я использую 2 пула потоков, каждый для разностной цели (их цели не имеют значения для этого вопроса). Бассейны созданы из одной и той же исходной нити следующим образом:Выполняют ли исполнители тему, из которой они были созданы?

private ScheduledExecutorService pool1 
    = Executors.newCachedThreadPool(new ManagerFactory(group, "Cached")); 
private ExecutorService pool2 
    = Executors.newScheduledThreadPool(3, new ManagerFactory(group, "Scheduled")); 


ManagerFactory класс:

private class ManagerFactory implements ThreadFactory { 

    private final ThreadGroup group; 
    private final String name; 

    private ManagerFactory(ThreadGroup group, String name) { 
     this.group = group; 
     this.name = name; 
    } 

    @Override 
    public Thread newThread(Runnable r) { 
     final Thread t = new Thread(group, r); 
     t.setName(name + " Manager Thread"); 
     return t; 
    } 
} 
  1. Когда эти пулы потоков создаются, будут ли они когда-либо использовать нить они были созданы для выполнения поставленной задачи?
  2. Если ответ на это не так, есть ли задержка при отправке новой задачи, которая должна быть выполнена?
    Под этим я имею в виду не задержку перед выполнением задачи, так как я знаю, что планировщики не могут гарантировать, когда задача будет выполнена. Чтобы лучше прояснить это, обратитесь к следующему примеру: Я отправляю задание на EDT. Будет ли EDT повесить вообще, пока задача будет отправлена?
  3. Как вы узнаете, какой из ExecutorServices будет использовать вызывающий поток, а какой нет?
+0

простые вопросы: 1. нет 2. да – jtahlborn

+0

1 на самом деле * возможно *, но только если вы используете Исполнителя с помощью «ThreadPoolExecutor.CallerRunsPolicy». –

+0

EDT, в цикле, принимает задачи из своей очереди и затем выполняет их. Доступ к очереди синхронизирован. Если EDT выполняет задачу точно, когда другая задача отправляется другим потоком, EDT (или этот поток) ждет незначительный период времени. –

ответ

2

Ответ на ваш первый вопрос действительно: no *. Поток, созданный исполнителем, не находится под контролем исполнителя, поэтому он не может использовать этот поток для запуска задач.

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

*) Фактически, это зависит от реализации используемого вами ExecutorService. Но большинство реализаций, таких как возвращаемые Executors.newCachedThreadPool и Executors.newScheduledThreadPool, создают собственные пулы потоков для запуска задач.

Чтобы ответить на ваш третий вопрос: посмотрите в документации по API конкретной реализации ExecutorService, которую вы используете.

+0

Благодарим за отзыв. Я полагаю, что мне следовало бы более ясно ответить на второй вопрос: я не спрашиваю, есть ли задержка до того, как задача выполнена, я знаю, что есть.Я спрашиваю, есть ли задержка при добавлении задачи. Так, например, если я добавлю задачу из EDT, повесил бы EDT вообще? – user3144349

+1

Собственно, это неправда. Нить, используемая исполнителем, зависит от исполнителя и может быть основным потоком. Ничего не существует в [javadoc] (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html) (то есть контракт), в котором говорится, что он должен использовать другой поток. – Bohemian

+0

Это зависит от точной реализации «ExecutorService», но, вероятно, именно то, что он делает, просто добавляет задачу в очередь, которая не является операцией, которая занимает много времени, поэтому не ожидается, что EDT будет висеть на этом , – Jesper

1

Да: Исполнители могут использовать основной поток, но ваш код не будет.

Согласно javadoc, договор Исполнителя заключается в том, чтобы запустить Runnable. Как это происходит с Исполнителем.

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

+2

Верный, но, возможно, вводящий в заблуждение. @ user3144349 спросил, будет ли ExeuctorService использовать поток, который _created_ it. Исполнитель может использовать поток, который _submits_ задание, но он никогда не будет использовать поток, создавший службу, если это не будет тот же поток, который отправляет задание. –

Смежные вопросы