Java线程池和运行时创建

时间:2013-07-13 06:49:32

标签: java multithreading threadpool

我有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)杀死特定设备/线程。

是否可以使用池选择单个线程并将其终止? 如果不是,最好的方法是什么?

非常感谢。

2 个答案:

答案 0 :(得分:2)

  

是否可以使用池选择单个线程并将其删除?

你放入threads的东西不是“线程”。它们是RunnableCallable个实例。因此,当您说要杀死某个帖子时,实际意味着您要取消已提交的任务。

如果要取消任务,则需要保留 Future方法返回的submit(task)对象,然后在其上调用cancel(boolean) 。如果您调用cancel(true),则当前正在运行任务的线程(如果有)将被中断。但是,如果您的任务旨在正确响应中断,那么这只会起作用。

你不能杀死运行任务的线程:

  • 执行此类操作的方法是已弃用。 (他们不安全
  • 无论如何,你无法掌握相关的Thread对象。

  

我认为ExecutorService用于管理不管理线程的任务。在我写的程序中,我想单独管理每个线程。

啊,我明白了。所以实际上你所描述的并不是一个线程 pool 。 (你真的应该对你的术语更加谨慎。这些术语意味着具体的事情。如果你使用错误的术语,人们就无法理解你!)

在这种情况下,是的,您需要一个线程数组,或者更可能是某个自定义“设备”类的数组,该类具有该设备线程的实例字段。然后,您安排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