我有Java应用程序,允许用户选择5到500之间的许多设备。 选择后,用户单击“开始”,程序将创建代表每个设备的线程。
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]);
}
这很好用,因为我可以在运行时以这种方式启动大量线程,我遇到的问题是管理它们。用户选项之一是允许(通过组合框中的GUI)杀死特定设备/线程。
是否可以使用池选择单个线程并将其终止? 如果不是,最好的方法是什么?
非常感谢。
答案 0 :(得分:2)
是否可以使用池选择单个线程并将其删除?
你放入threads
的东西不是“线程”。它们是Runnable
或Callable
个实例。因此,当您说要杀死某个帖子时,实际意味着您要取消已提交的任务。
如果要取消任务,则需要保留 Future
方法返回的submit(task)
对象,然后在其上调用cancel(boolean)
。如果您调用cancel(true)
,则当前正在运行任务的线程(如果有)将被中断。但是,如果您的任务旨在正确响应中断,那么这只会起作用。
你不能杀死运行任务的线程:
啊,我明白了。所以实际上你所描述的并不是一个线程 pool 。 (你真的应该对你的术语更加谨慎。这些术语意味着具体的事情。如果你使用错误的术语,人们就无法理解你!)我认为ExecutorService用于管理不管理线程的任务。在我写的程序中,我想单独管理每个线程。
在这种情况下,是的,您需要一个线程数组,或者更可能是某个自定义“设备”类的数组,该类具有该设备线程的实例字段。然后,您安排GUI在相关“设备”的线程对象上调用Thread.interrupt()
。
这取决于你的运行/调用方法中关于中断标志等的runnable / callable实例。
答案 1 :(得分: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
。