2013-07-13 5 views
0

У меня есть приложение Java, которое позволяет пользователю выбирать несколько устройств в диапазоне от 5 до 500. После того, как пользователь нажимает кнопку запуска, а программа создает поток, который представляет каждое устройство.Пул потоков Java и время выполнения

ExecutorService pool = Executors.newFixedThreadPool(jSlider1.getValue()); 
Upload[] threads = new Upload[jSlider1.getValue()]; 

for (int i=0; i < jSlider1.getValue(); i++) 
{    
    ThreadListComboBox.addItem("Number "+i);              
    threads[i] = new Upload("Squeak"+i, this.OutputDisplay);    
} 

for (int c=0; c < threads.length; c++) 
{ 
    pool.submit(threads[c]); 
} 

Это прекрасно работает, так что я могу начать много потоков во время выполнения таким образом, проблема заключается в управлении ими. Один из параметров пользователя - разрешить (через графический интерфейс пользователя из combobox) убить определенные устройства/потоки.

Возможно ли использовать пул, чтобы выбрать один поток и убить его? Если это не лучший способ достичь этого?

Большое спасибо.

+1

Я думаю, вам нужно создать свой собственный [пул] (http://www.codeproject.com/Articles/616109/Java-Thread-Tutorial#trpool) –

ответ

2

Возможно ли использование пула, чтобы выбрать нить и убить его?

То, что вы помещаете в threads, не являются «нитями». Это Runnable или Callable экземпляров. Поэтому, когда вы говорите, что хотите убить нить, вы на самом деле означает, что вы хотите отменить отправленную задачу.

Если вы хотите отменить задание, то вам нужно держатьFuture объект, что submit(task) метод возвращает, а затем вызвать cancel(boolean) на него. Если вы вызываете cancel(true), поток (если есть), который в данный момент запущен, будет прерван. Тем не менее, это будет работать только в том случае, если ваша задача призвана правильно реагировать на прерывание.

Вы не можете убить нить запуска задачи:

  • методы ведения такого рода вещи являются осуждается. (Они небезопасные)
  • Вы все равно не сможете получить доступ к соответствующему объекту Thread.

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

А ... Я вижу. Таким образом, на самом деле то, что вы описываете, НЕ является нитью пулом. (Вы действительно должны быть намного более осторожны с вашей терминологией. Эти термины означают конкретные вещи. Если вы используете неправильные термины, люди не могут вас понять!)

В таком случае вам нужен массив потоки или, более вероятно, массив некоторого настраиваемого класса «устройства», который имеет поле экземпляра для потока устройства. Затем вы организуете, чтобы GUI вызывал Thread.interrupt() на объект потока для соответствующего «устройства».

Это зависит от ваших исполняемых/вызываемых экземпляров относительно флага прерывания и т. Д. В их методах запуска/вызова.

+0

Привет, Да, я понял, что теперь понял неправильно. Простым способом является простой make ArrayList из потоков. private ArrayList pool = new ArrayList (); – DevilCode

+0

@DevilCode - нет простого способа. И кроме того, вы не должны. Вы делаете это правильно, используя «ExecutorService». Что вам нужно сделать, так это сохранить и использовать объекты 'Future'. –

+0

Я думал, что ExecutorService предназначен для управления задачами, не управляющими потоками. В программе, которую я пишу, я хочу управлять каждой нитью индивидуально. – DevilCode

1

Наивный способ может быть реструктурировать класс выглядеть следующим образом

... 
...  
private volatile boolean running; 

public void stop() { 
    running = false; 
} 

@Override 
public void run() { 
    while (running) { 
     //do some amount of work 
    } 
} 

Или вы можете обернуть рабочие лошадки (ваше устройство нитей) в будущем.

List<Future<Output>> taskList = new ArrayList<Future<Output>>(); 
for (int i = 0; i < maxThreads; ++i) { 
    taskList.add(executor.submit(upLoadObject)); 
} 


// Instead of iterating through the above list and adding tasks individually 
// you can also invoke add all the Future<Output> in a list and then invoke it 
// together using 
// executor.invokeAll(listOfCallables); 


//User says shoot the nth task 
Future<Output> toCancelTask = taskList.get(n); 

//Cancel the task and interrupt it while doing so. 
toCancelTask.cancel(true); 

//You can also show progress by iterating through the taskList 
for (Future<Output> task : taskList) { 
    if (task.isDone()) { 
     //some jingles. .. 
    } 
} 

Ваш Upload класс может реализовывать Callable, если вы хотите, чтобы вернуть любой результат из этого потока.

+0

В соответствии с документом thread.stop() теперь амортизируется = ((старые способы исчезли ... sob). Любой шанс вы могли бы перейти ко второму варианту более подробно. – DevilCode

+0

Эй, это ваш собственный метод stop(). Вы опросили переменную 'running'. Зачем мне иметь переменную исполняемого экземпляра, если бы я был _ever_, чтобы использовать stop()? – bsd

+0

ArrayList pool = new ArrayList (); pool.get (int). не загружать класс, поэтому я не могу получить доступ к общедоступным методам get/set для переключения с runnable из true в false. – DevilCode

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