【问题标题】:Understanding Java Concurrency with thread用线程理解 Java 并发
【发布时间】:2023-03-22 00:43:01
【问题描述】:

我目前正在阅读http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html的java并发教程

我无法理解“子类或可运行”下的以下几行?

当线程池执行 Runnable 时,很容易将 Runnable 实例排队,直到池中的线程空闲。

【问题讨论】:

    标签: java multithreading concurrency runnable


    【解决方案1】:

    正如文章指出的那样,它们都“有效”,尽管一般来说,您应该使用Runnable(或者如果需要参数/结果Callable 和Future)而不是继承Thread。正如您所指出的,这更加灵活 - 它将执行的内容与执行的人分开。扩展 Thread 不必要地将这两个概念在同一个实例中紧密耦合在一起,打破了 single responsibility 的 OO 原则。

    当您的手被 API 强制执行时,有时您必须将可执行代码实现为 Thread 的子类。例如,Runtime.addShutdownHook(Thread) 要求您在关机时执行的代码注册为 Thread 实例。但是,如果您不处理这些特定情况之一,请始终使用Runnable。

    【讨论】:

      【解决方案2】:

      作者只是想传达,根据他的说法,Runnables 更容易与线程池一起使用。线程池的一个概念是您可以有固定数量的线程(比如 10 个)等待接受作业。如果所有 10 个线程都忙于运行线程,则可以将未完成的工作排队,直到池中的这些线程之一空闲。

      【讨论】:

      • 那么,如果我们有固定数量的线程来做作业,那么使用 Thread 扩展线程和 Runnable 实现的线程有什么区别。
      • 检查一下:coderanch.com/how-to/java/ExtendingThreadVsImplementingRunnable 底线:通过实现 Runnable 而不是扩展 Thread,您可以最大限度地减少以后如果您决定使用 Executor 可能需要更改的代码量。
      • 和 ofcorse、executors 和所有新的好东西都可以与 Runnables 一起使用.....在我看来,对于 J5 之后的简单、直接的应用程序,你不应该担心线程
      【解决方案3】:

      Jenkov 强调,在 Subclass 或 Runnable 实现之间进行选择是由于偏好(如果有的话)。

      他以thread pool pattern 为例说明为什么可运行接口实现更加灵活。我支持他最初的假设,但主要是因为 Runnable 对象可以继承 Thread 以外的类。

      我不太明白,使用 java 本机库即线程子类构建线程池将如何那更加麻烦。 java.util.concurrent.ThreadPoolExecutor。我希望 Jenkov 能提供一个例子……

      【讨论】:

      • 问题在于每个Thread 对象实际上是一个新的Java 线程(通常对应于一个本地线程)。线程池的目的是避免在不必要的情况下创建新线程,因为这非常昂贵。
      【解决方案4】:

      Jenkov 在他的并发教程中进一步描述了使用 ExecutorService 工厂方法的固定和缓存线程池。看看这里:http://tutorials.jenkov.com/java-util-concurrent/executorservice.html。使用创建这些线程池的 Java 并发实用程序,使用可运行对象变得更加容易。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多