0

我有一个主要过程main。它创建了 10 个线程(比如说),然后我想要做的是以下内容:

while(required){
Thread t= new Thread(new ClassImplementingRunnable());
t.start();
counter++;
}

现在我有了这些线程的列表,并且对于每个线程我想做一组进程,对所有线程都是一样的,因此我把那个实现放在ClassImplementingRunnable.

现在线程完成执行后,我想等待所有线程停止,然后再次调用它们,但是这次我想串行而不是并行执行它们。

为此,我加入每个线程,等待它们完成执行,但之后我不知道如何再次唤起它们并连续运行那段代码。我可以做类似的事情吗

for(each thread){
t.reevoke(); //how can i do that.
t.doThis();  // Also where does `dothis()` go, given that my ClassImplementingRunnable is an inner class.
}

此外,我想使用相同的线程,即我希望从他们离开的地方继续,但以串行方式。我不确定如何处理最后一段伪代码。请帮忙。使用java。

4

4 回答 4

3

如果要串行执行,只需使用

for (int i = 0; i < 10; i++)
  new ClassImplementingRunnable().run();

所有任务将在同一个线程中一个接一个地运行。这是实现您想要的最干净的方法。

更新

在您发表评论后,很明显您实际上不想再次运行相同的任务,而是打印它们计算的结果。这会更简单:

  1. ClassImplementingRunnable实例添加到任务列表中;
  2. 在自己的线程中运行每个任务;
  3. 加入所有线程;
  4. 编写一个for循环来打印每个ClassImplementingRunnable实例的结果。

你已经有了 2 和 3。

于 2012-08-28T09:28:59.050 回答
3

您无法重新启动线程。

您可以做的是使用 java.util.concurrent 包等待线程完成并在主线程中重新运行可运行对象以按顺序运行它们 - 通过将可运行对象放在列表中,您可以在顺序运行期间访问它们。

ExecutorService executor = Executors.newFixedThreadPool(10);
List<Runnable> runnables = new ArrayList<Runnable> ();

for (int i = 0; i < 10; i++) {
    Runnable r = new ClassImplementingRunnable();
    runnables.add(r);
    executor.submit(r);
}

executor.shutdown();
//wait until all tasks are finished
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);

//re run the tasks sequentially
for (ClassImplementingRunnable r : runnables) {
    //the method below can access some variable in 
    //your ClassImplementingRunnable object, that was 
    //set during the first parallel run
    r.doSomethingElse(); 
}
于 2012-08-28T09:31:25.280 回答
0

尽管这里有一些很好的答案,但我不确定您最初的问题是否已得到解答。

现在线程完成执行后,我想等待所有线程停止,然后再次调用它们,但是这次我想串行而不是并行执行它们。

您正在将正在运行的线程与它的对象混淆。执行以下操作是一种非常常见的模式(尽管通常使用ExecutiveService类做得更好):

List<ClassExtendingThread> threads = new ArrayList<ClassExtendingThread>();
// create your list of objects
for (int i = 0; i < 10; i++) {
    ClassExtendingThread thread = new ClassExtendingThread(...);
    thread.start();
    threads.add(thread);
}

for (ClassExtendingThread thread : threads) {
    // now wait for each of them to finish in turn
    thread.join();
    // call some method on them to get their results
    thread.doThis();
}

请注意,我将您的课程更改为扩展Thread。通常最Runnable好像你一样实现,但如果你要加入和回调对象,扩展Thread会使代码更容易。

因此,您创建对象实例,将它们作为线程启动,然后join()与它们一起等待它们完成并同步它们的内存。一旦你join()有了线程,你就可以调用你想要的对象的任何方法。这根本不会“重新唤起”线程。它只是访问对象内部的字段。如果您尝试在线程运行时执行此操作,那么您需要担心synchronization.

于 2012-08-29T18:21:02.430 回答
0

我猜你想要类似 ExecutorCompletionService

从 Java 文档复制的示例。

用法示例。假设您有一组求解某个问题的求解器,每个求解器返回某种类型的值 Result,并希望同时运行它们,处理每个返回非空值的结果,在某些方法中使用(Result r)。你可以这样写:

void solve(Executor e,
          Collection<Callable<Result>> solvers)
 throws InterruptedException, ExecutionException {
   CompletionService<Result> ecs
       = new ExecutorCompletionService<Result>(e);
   for (Callable<Result> s : solvers)
       ecs.submit(s);
   int n = solvers.size();
   for (int i = 0; i < n; ++i) {
       Result r = ecs.take().get();
       if (r != null)
           use(r);
   }

}

于 2012-08-28T09:31:12.457 回答