如何在Java中使用线程池概念

如何在Java中使用线程池概念

本文介绍了如何在Java中使用线程池概念?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在java中创建一个http代理服务器。我有一个名为 Handler 的类,它负责处理来自Web浏览器和Web服务器的请求和响应。我还有另一个名为 Copy 的类,它将inputStream对象复制到outputStream对象。这两个类都实现了 Runnable 接口。我想在我的设计中使用线程池的概念,但我不知道如何去做!任何提示或想法都将受到高度赞赏。

I am creating a http proxy server in java. I have a class named Handler which is responsible for processing the requests and responses coming and going from web browser and to web server respectively. I have also another class named Copy which copies the inputStream object to outputStream object . Both these classes implement Runnable interface. I would like to use the concept of Thread pooling in my design, however i don't know how to go about that! Any hint or idea would be highly appreciated.

推荐答案

我建议您查看Executor和ExecutorService。他们添加了许多好东西,以便更容易使用线程池。

I suggest you look at Executor and ExecutorService. They add a lot of good stuff to make it easier to use Thread pools.

...

@ Azad提供了一些很好的信息和链接。您还应该购买并阅读 Java Concurrency in Practice 一书。 (通常缩写为JCiP)注意stackoverflow大假发 - 亚马逊的一些收入链接怎么样?

@Azad provided some good information and links. You should also buy and read the book Java Concurrency in Practice. (often abbreviated as JCiP) Note to stackoverflow big-wigs - how about some revenue link to Amazon???

以下是我如何使用和利用的简要总结带有线程池的ExecutorService。假设您想要池中的8个线程。

Below is my brief summary of how to use and take advantage of ExecutorService with thread pools. Let's say you want 8 threads in the pool.

您可以使用ThreadPoolExecutor的完整功能构造函数创建一个,例如

You can create one using the full featured constructors of ThreadPoolExecutor, e.g.

ExecutorService service = new ThreadPoolExecutor(8,8, more args here...);

或者您可以使用更简单但可自定义较少的Executors工厂,例如:

or you can use the simpler but less customizable Executors factories, e.g.

ExecutorService service = Executors.newFixedThreadPool(8);

您立即获得的一个优势是能够 shutdown() shutdownNow()线程池,并通过 isShutdown()或<$来检查此状态c $ c> isTerminated()。

One advantage you immediately get is the ability to shutdown() or shutdownNow() the thread pool, and to check this status via isShutdown() or isTerminated().

如果您不太关心您想要运行的Runnable,或者它们非常好写,自包含,永不失败或适当记录任何错误等...你可以致电

If you don't care much about the Runnable you wish to run, or they are very well written, self-contained, never fail or log any errors appropriately, etc... you can call

execute(Runnable r);

如果您关心结果(例如,它计算pi或从网页下载图像) )和/或你关心是否有异常,你应该使用一个返回Future的提交方法。这允许您在将来的某个时间检查任务 isDone()并通过 get()。如果有异常, get()将抛出它(包含在ExecutionException中)。注意 - 即使你的Future没有返回任何东西(它是Void类型),调用 get()(忽略void结果)仍然是一个好习惯。测试一个异常。

If you do care about either the result (say, it calculates pi or downloads an image from a webpage) and/or you care if there was an Exception, you should use one of the submit methods that returns a Future. That allows you, at some time in the future, check if the task isDone() and to retrieve the result via get(). If there was an Exception, get() will throw it (wrapped in an ExecutionException). Note - even of your Future doesn't "return" anything (it is of type Void) it may still be good practice to call get() (ignoring the void result) to test for an Exception.

但是,检查Future是一个鸡和蛋的问题。线程池的重点是不阻塞地提交任务。但Future.get()阻塞,而Future.isDone()引发了哪个线程调用它的问题,以及如果没有完成它会做什么 - 你睡觉()和阻止吗?

However, this checking the Future is a bit of chicken and egg problem. The whole point of a thread pool is to submit tasks without blocking. But Future.get() blocks, and Future.isDone() begs the questions of which thread is calling it, and what it does if it isn't done - do you sleep() and block?

如果你同时提交一个已知的大量相关的任务,例如,你正在进行一些大的数学计算,比如可以并行完成的矩阵乘法,那里获得部分结果没有特别的优势,你可以调用 invokeAll()。调用线程将阻塞,直到所有任务完成,此时您可以在所有期货上调用 Future.get()

If you are submitting a known chunk of related of tasks simultaneously, e.g., you are performing some big mathematical calculation like a matrix multiply that can be done in parallel, and there is no particular advantage to obtaining partial results, you can call invokeAll(). The calling thread will then block until all the tasks are complete, when you can call Future.get() on all the Futures.

如果任务更加脱节,或者你真的想要使用部分结果怎么办?使用ExecutorCompletionService,它包装ExecutorService。任务完成后,它们将添加到队列中。这使得单个线程可以轻松地轮询和从队列中删除事件。 JCiP有一个很好的网页应用程序示例,它可以并行下载所有图像,并在它们可用于响应时立即呈现它们。

What if the tasks are more disjointed, or you really want to use the partial results? Use ExecutorCompletionService, which wraps an ExecutorService. As tasks get completed, they are added to a queue. This makes it easy for a single thread to poll and remove events from the queue. JCiP has a great example of an web page app that downloads all the images in parallel, and renders them as soon as they become available for responsiveness.

这篇关于如何在Java中使用线程池概念?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 17:46