2013-07-23 4 views
0

У меня есть класс, который реализует Runnable«Маршрутизация» задачи внутри ThreadPoolExecutor

public class MyRunnable implements Runnable { 
    private long RID = <SOME_LONG_ID_VALUE>; 
    public long getRID() { return this.RID; } 
    public void run { 
     System.out.println("HAI!"); 
    } 
} 

Есть ли способ «маршрут» задачи внутри ThreadPoolExecutor по RID полю (я имею в виду, если нить N 3 работает Runnable с RID = 1, то следующий вкус с RID = 1 должен выполняться нитью N 3 (если он жив)) Спасибо.

+0

Какова цель этого? Я не вижу никого. Могут быть много случаев, что если N 3 занят, или он больше не существует и т. Д. – Jatin

+0

В двух словах: цель состоит в том, чтобы избежать состояния гонки и выполнить MyRunnables с одинаковыми идентификаторами RID, чтобы они были отправлены ThreadPoolExecutor. –

+0

О случаях, описанных выше: Если Thread N3 больше не существует, ThreadPoolExecutor должен создать новый поток с «id» 3. Если поток занят, эта задача не должна выполняться до тех пор, пока поток не станет бесплатным. –

ответ

0

Ну, я не думаю, чтобы избежать состояния гонки (как упоминалось в ваших комментариях), это могло бы помочь в любом случае. Todo:

Если Thread N3 действительно больше не не существует, ThreadPoolExecutor не должны создавать новый поток с "ид" 3. Если поток занят, эта задача не должна быть выполнена до резьбы будет FRE

ThreadPoolExecutor Управление потоками для вас. Чтобы сделать это, невозможно сделать это с существующей библиотекой, вам, вероятно, придется создать свой собственный, чтобы сделать это. Если ваша логика и безопасность потоков зависит от RID, чем я довольно рекомендуем использовать Карту RID и ReentrantLock, somethign так:

ConcurrentHashMap<Long, ReentrantLock> map = new ConcurrentHashMap<Long, ReentrantLock>(); 

public synchornized ReentrantLock getLock(Long id){ 
    ReentrantLock lock = map.get(id); 
    if(lock!=null) 
     return lock; 
    else{ 
     map.put(id, new ReentrantLock()); 
} 

В вашем Runnable, вы можете получить lock к желаемым и синхронизировать соответственно.

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

0

Как я понимаю, для каждого RID у вас есть контекст выполнения, и вы хотите последовательно выполнить все объекты MyRunnable в этом контексте.

Ваша ошибка в том, что вы пытаетесь связать этот контекст с потоком. Лучше представить этот контекст актером. Вы можете использовать широко известные актерские рамки, такие как Akka, но для вашей цели простой Actor implementation будет работать.

EDIT: Другая точка зрения: поскольку реализация Actor имеет единственный способ интерфейса execute, ее можно рассматривать как последовательный исполнитель, выполняющий поставленные задачи поочередно. И поскольку у него нет собственного потока, но он использует другого исполнителя, который делится между всеми Актерами, его можно назвать Вторичным Исполнителем.

+0

Не совсем. Основная цель - запустить MyRunnables строго в том порядке, в котором они были добавлены в ThreadPoolExecutor (не параллельно, в одном потоке). Они должны работать строго последовательно. –

+0

Итак, контекст - это не что иное, как заказ. Однако этот порядок должен иметь свое представление, и рекомендуемая реализация Actor выглядит достаточно хорошо для него. Другими словами, эту реализацию Актера можно назвать вторичным Исполнителем, см. Отредактированный ответ. –

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