【问题标题】:Invoking different methods on threads在线程上调用不同的方法
【发布时间】:2012-08-28 09:23:38
【问题描述】:

我有一个主进程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。

【问题讨论】:

  • 所以您想测试同时(并行)启动所有线程与串行启动它们是否更快?
  • 什么是doThis?是指Runnablesrun方法吗?
  • this time i want to do them serially not in parallel. 在这种情况下,您不需要多个线程,您只需要一个,即调用线程的那个。线程一旦完成就无法重新启动。
  • 无法重新启动线程。完成后,您将必须使用您的可运行文件创建一个新线程。
  • 但是如果我创建新线程他们不会知道以前的线程做了什么,那么他们创建的所有对象都会丢失,或者不会?如何访问之前线程所做的更改?

标签: java multithreading


【解决方案1】:

您无法重新启动线程。

您可以做的是使用 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(); 
}

【讨论】:

  • 这个答案比我的要好,因为它敦促切换到 Executors 并显示执行此操作所需的实际代码。使用这种方法,可以通过使用Callable 并立即开始打印Future.get() 的结果来改进解决方案,在等待任务完成时根据需要阻塞。
【解决方案2】:

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

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

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

更新

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

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

你已经有了 2 和 3。

【讨论】:

  • 说,我的第一个线程创建了一些列表,第二个线程也创建了一些列表,依此类推,但都包含不同的数据。现在如果我想打印那些数据怎么办,如果我把这个打印的东西只放在 run 方法中,它会给我带来奇怪的结果,因为它们都会相互干扰。
  • 和你建议的方式,我想我无法记住每个线程停止的状态。还是我会?
  • 那你还没有明确要求。一旦你运行了一个任务,再次运行完全相同的任务就没有什么意义了。如果要打印结果,这与计算结果不同。然后您需要的只是一个简单的for 循环,它读取由这些任务计算的列表并打印出来。
【解决方案3】:

我猜你想要类似的东西 ExecutorCompletionService

从 Java 文档复制的示例。

使用示例。 假设您有一组求解器来解决某个问题,每个求解器都返回某种类型的 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);
   }

}

【讨论】:

    【解决方案4】:

    虽然这里有一些很好的答案,但我不确定你最初的问题是否已经得到解答。

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

    您将正在运行的线程与它的对象混淆。这是一种非常常见的模式(尽管通常使用 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

    【讨论】:

      猜你喜欢
      • 2013-11-09
      • 2014-12-12
      • 1970-01-01
      • 2011-11-24
      • 2012-01-07
      • 1970-01-01
      • 2018-07-14
      • 1970-01-01
      相关资源
      最近更新 更多