7

我仍然很难将头绕在线程上,我正在尝试以最简单的方式做到这一点。我知道线程都必须有一个从 Runnable 类继承的 run 方法,但它们也可以有其他方法,对吗?

原因是,我有一个带有一些私有变量和一个运行方法的线程。它调用它的运行函数,一旦完成,我想用完全相同的运行方法重用线程。它做的事情完全相同,只是变量不同。所以我可以添加类似 setArray 方法的东西(线程包含一个私有字节数组),这样我就可以简单地用这个新数组再次调用 run,或者这是不允许的。我想简单地说,它就像

Thread thread = new MyThread();
thread.start();

// Check if the thread has finished in a non-blocking way
if (thread.isAlive() == false) {
    thread.setArray(newArray)
    thread.start();
}

基本上我只有固定数量的线程,当第一个线程完成运行时,我想稍微更改一下参数并让它再次运行。我不希望他们死,这似乎是 join 所做的。

对于具体问题,我说 4 个线程,每个线程都给出一个更大字节数组的集合大小块。每个线程使用 Deflater 压缩该数组并将其结果传递给处理同步的管理器对象。一旦第一个线程(如获得数组第一部分的线程,而不是第一个完成的线程)完成,它就会移动到下一个未分配给线程的块。

我知道线程池是一种选择,但它似乎有点矫枉过正,而且我真的不明白它们(我仍然遇到普通线程的问题)。

4

4 回答 4

15

首先,最好使用标准Thread类(不要继承它!)并将您的应用程序代码放入实现Runnable. 这使得将应用程序逻辑与管理线程的问题分开变得更加容易。

其次,您必须了解 Thread 对象仅调用该run方法一次。在run方法返回(或因异常终止)后,Thread 对象就死了,无法恢复生机。

因此,如果你想“重用”Thread实例,你必须安排该run方法是一个循环,(不知何故)等待下一件事情完成。在不知不觉中,您正在实现一个线程池。

线程池还有另一种(更“现代”)替代方案。创建一个ExecutorService实例,并使用该submit()方法提交Runnable实例以供执行。接口 javadoc 有一个很好的使用示例,使用带有私有线程池的执行器服务实例。如果您愿意,您可以重用这些Runnable实例,但通常每次创建新实例更简单(也更安全)。

于 2012-10-28T05:42:57.737 回答
1

为实现 Runnable 的代码创建一个单独的类。您每次都需要创建新的 Thread 对象,但使用单个 Runnable 对象构建这些对象。run 方法将被每个线程重用。

于 2012-10-28T05:26:01.160 回答
1

一个线程总是只启动一次,只运行一次,然后只运行一次。所以你不能按照你建议的方式多次调用线程上的 start() 。

因此,无论哪种方式,您都必须:

  • 有一个线程,在它的 run() 方法中以一种或另一种方式,使用不同的参数集执行每个方法调用。
  • 为每个“运行”启动一个新线程(对您实际想要做的事情的方法调用)。

哪种实现更合适取决于您的确切应用程序。但总的来说,将线程视为与其他子任务并行运行的子任务是有帮助的。所以总的来说:

  • 如果您有一系列独立的“运行”,而您没有理由彼此并行运行,请安排这些运行在单个 Thread.run() 方法中一个接一个地执行;
  • 如果您有一系列任务也可以彼此并行运行,请将每个任务放在一个单独的线程中。

线程池通常用于在任何给定时刻您可以执行一些任意任务并且这些任务可以并行运行的情况。例如,在典型的服务器上。想象一个 Web 服务器在任意时间点接收来自不同客户端的页面请求:每个请求都可以在某个任意时间点出现,并且来自一个客户端的页面请求完全独立于来自另一个客户端的请求。原则上,您不关心哪些请求与哪些请求并行运行,除了您的机器具有资源限制(例如 CPU 数量)之外。对于这种类型的情况,您实际上想要“在任意线程中运行任意任务,最多并行运行 X 个任务”,您通常会使用线程池。

于 2012-10-28T05:38:30.640 回答
-3

线程基本上只是具有状态和运行方法的对象。这是一个示例线程:

public class ThreadWithState implements Runnable {

  private Object state;

  public ThreadWithState(Object state) {
    this.state = state;
  }

  public void run() {
    // Do something with state
  }
}

线程一般是并行执行的,否则就失去了多线程的全部意义。因此,我们尝试使用线程池来执行,如下面的 Driver 类所示:

public class Driver {

  public static void main(String[] args) {
    ThreadWithState thread = new ThreadWithState(null);
    ThreadWithState thread2 = new ThreadWithState(new Object());
    ThreadWithState thread3 = new ThreadWithState(new Object());
    ThreadWithState thread4 = new ThreadWithState(new Object());

    ExecutorService service = Executors.newFixedThreadPool(4);
    service.submit(thread);
    service.submit(thread2);
    service.submit(thread3);
    service.submit(thread4);
    service.shutdown();
  }
}
于 2012-10-28T05:42:17.427 回答