Как изменить цель Runnable потока во время выполнения

Я хочу создать свой собственный ExecutorService на Java, который может «отправить (вызываемая задача)» заданную задачу. Я намеревался использовать пул потоков, состоящий из нескольких «Threads (Runnable target)». Идея состоит в том, чтобы создать фиксированное количество потоков, которые удаляют объекты FutureTask из очереди из списка, который был заполнен методом «отправить». Объекты FutureTask также были созданы в методе отправки. Моя проблема в том, что я могу передать объект Runnable (здесь: FutureTask) потоку только при создании потока (через конструктор), но, очевидно, FutureTasks необходимо назначать потоку динамически (когда элемент удаляется из списка ). Есть какой-либо способ сделать это?

// content of submit, parameter: myTask
FutureTask<V> newFutureTask = new FutureTask<V>(myTask);
taskQueue = new BlockingQueue<FutureTask<V>>();
try {
    taskQueue.put(newFutureTask);
} catch (InterruptedException ex) { }
return newFutureTask;

// remove item from list and hand it over to thread
// method within MyThread extends Thread (thread pool) class
void exec() {
    FutureTask<V> task;
    try {
        task = taskQueue.take();
        // TODO: run task somehow????
        } catch(InterruptedException ex) { }
}

person Patrick    schedule 01.06.2019    source источник
comment
Я полагаю, вы изобретаете велосипед в образовательных целях?   -  person GhostCat    schedule 01.06.2019


Ответы (2)


См. немного псевдокода:

while (true) {
   task = fetch task
   If no task: wait/yield
   Else: execute task 
}

Другими словами: вам просто нужно реализовать метод run(), который зацикливает и выполняет метод run любого Runnable (или того, что ему передается). Если работа недоступна, эти методы приостанавливаются или ждут уведомления.

person GhostCat    schedule 01.06.2019

Во-первых, FutureTask это Runnable, поэтому вы можете просто task.run(); в строке с // TODO.

Во-вторых, вам вовсе не нужно taskQueue = new BlockingQueue<FutureTask<V>>();. Сделайте свою реализацию ExecutorService дополнением к существующему Executor:

class MyExecutorService implements ExecutorService {

   private final Executor executor;

   public MyExecutorService(Executor executor) {
       this.executor=executor;
   }

   public Future<?> submit(Runnable task) {
       FutureTask task = new FutureTask(task);
       executor.exec(task);
       return task;
   }
}
person Alexei Kaigorodov    schedule 01.06.2019
comment
Понятно. Большое тебе спасибо. - person Patrick; 02.06.2019