我有一个处理某些内容的类。我正在尝试并行运行此类的多个实例。
但是,我不确定在 TaskManager.startAll()
中,当我调用 r.go()
时,这是否会导致 r 开始运行它自己的线程,还是在主线程内?
我得到的总执行时间似乎非常长,尽管我尝试优化,但似乎没有任何效果。另外,如果我在 Netbeans 中对我的项目运行探查器,它会显示所有线程都处于 hibernate 状态。所以我想知道我是否做错了什么?
这是类的结构:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
以下是它们的运行/管理方式:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
最佳答案
确实,你没有“做对”。如果您想创建多线程 Java 应用程序,可以从 java.util.concurrent
包开始。
从您的代码看来,您希望并行运行十个任务。我假设在“数字运算和处理”之后,您将需要聚合结果并在主线程中对它们执行一些操作。为此,ExecutorService
的 invokeAll()
方法效果很好。
首先,实现 Callable
来完成您在 process()
方法中显示的工作。
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
@Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
然后创建您的任务并运行它们。这将取代您的 main()
方法:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
关于Java 多线程似乎无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19144012/