在java中编写多线程Internet服务器时,主线程启动新的 那些并行提供传入请求。
如果主线程没有等待(.join()
),是否有任何问题?
(显然荒谬的是创建一个新线程然后等待它)。
我知道,在实际情况下,你应该(或“你必须”?)实现一个池 线程在它们变为空闲时“重新使用”它们以获得新请求。
但是对于小型应用程序,我们应该使用一个线程池吗?
答案 0 :(得分:8)
您无需等待线程。
他们可以自己完成运行(如果它们已经生成执行一个特定任务),或者无限期运行(例如在服务器类型的环境中)。
然而, 应该处理中断并响应关闭请求。有关如何正确执行此操作,请参阅this article。
如果您需要一组线程,我会使用池和executor方法,因为它们会为您管理线程资源管理。如果您正在编写多线程网络服务器,那么我将调查使用(比方说)servlet容器或Mina等框架。
答案 1 :(得分:1)
Thread.join()允许你等待Thread结束,这与你开始一个新线程时的想法大致相反。完全,你启动新线程与原始线程并行完成。
只有当你真的需要等待衍生线程完成时,才应该加入()它。
答案 2 :(得分:1)
您的方法中唯一的问题是它不能超出某个请求率。如果请求的速度超过服务器能够处理的速度,则线程数将不断增加。由于每个线程增加了一些开销并使用了CPU时间,处理每个请求的时间会变长,因此问题会变得更糟(因为线程数量上升得更快)。最终没有任何请求可以被处理,因为所有的CPU时间都浪费了开销。可能你的应用程序会崩溃。
另一种方法是使用具有固定线程上限的ThreadPool(取决于硬件的功率)。如果请求的数量超过了线程能够处理的数量,则某些请求将不得不在请求队列中等待太长时间,并且会因超时而失败。但是应用程序仍然可以处理其余的传入请求。
幸运的是,Java API已经提供了一个很好且灵活的ThreadPool实现,请参阅ThreadPoolExecutor。使用它可能比使用原始方法实现所有内容更容易,因此没有理由不使用它。
答案 3 :(得分:0)
如果你需要他们的结果或者需要做一些清理,你应该等待你的线程,只有在它们全部死亡之后才能进行清理,否则不行。
对于线程池:只要你有一些非固定数量的任务要运行,我会使用它,即如果数量取决于输入。
答案 4 :(得分:0)
我想收集这个有趣(对我来说)问题的主要想法。
我不能完全同意“你 不需要等待线程“。 只有在你不这样做的意义上 加入一个线程(并没有 指向它的指针)一旦线程是 完成后,它的资源被释放 (对吧?我不确定)。
仅使用线程池 必须避免开销 线程创建,因为......
您可以限制并行数量 通过记帐运行线程,使用共享变量(并且没有线程池),其中有多少个 已经开始但尚未完成。