Поток, который может перезапустить на основе условия - PullRequest
1 голос
/ 31 марта 2011

Основная идея заключается в том, что у меня есть встроенная функция, которую я хочу вызвать в фоновом потоке с выбранным пользователем значением, и поток не может быть прерван при запуске.Если пользователь решает изменить значение, используемое для выполнения задачи во время работы потока (они могут сделать это из графического интерфейса пользователя), поток должен завершить свою задачу с предыдущим значением, а затем перезапустить с новым значением.Когда задача выполнена и значение не изменилось, поток должен завершиться и вызвать функцию обратного вызова.

Вот как мой текущий код выглядит для начальной части потока:

volatile int taskValue;
volatile boolean taskShouldRestart;

void setTaskValue(int value)
{
  taskValue = value;

   synchronized (threadShouldRestart)
   { 
     if task thread is already running
         threadShouldRestart = true
     else
     {
         threadShouldRestart = false
         create and start new thread
     }
   }
}

И фактический рабочий поток выглядит следующим образом:

while (true)
{
    nativeFunctionCall(taskValue);

    synchronized (threadShouldRestart)
    { 
       if (!threadShouldRestart)
       {
         invokeTaskCompletedCallbackFunction();
         return;
       }
    }
}

Я блокирую часть "threadShouldRestart", потому что, например, я не хочу, чтобы это значение изменилось на true, так как поток решает, что это сделано, что означаетпоток не будет перезапущен, когда это было задумано.

Существуют ли какие-либо более чистые способы сделать это или классы утилит Java, которые я мог бы использовать?

Ответы [ 2 ]

0 голосов
/ 31 марта 2011

Рассматривали ли вы ThreadPoolExecutor? Кажется, она хорошо подходит для вашей проблемы, так как вы упомянули, что вам не нужно перезапускать или останавливать поток, который уже запущен.

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html

Пользователь может отправить столько задач, сколько ему нужно, в очередь задач, задачи будут обрабатываться одновременно с некоторым количеством рабочих потоков, которое вы определили в конструкторе ThreadPoolExecutor.

0 голосов
/ 31 марта 2011

Вы можете создать свой метод run() следующим образом:

public void run() {
    int currentTaskValue;
    do {
        currentTaskValue = taskValue;
        // perform the work...
    } while (currentTaskValue != taskValue);
}

Я думаю, для этого достаточно объявления volatile для taskValue, поскольку чтение и запись примитивов не превышает 32 битатомные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...