http请求的线程池

Maz*_*aze 5 java concurrency performance multithreading http

我有几个关于并发架构和性能的问题。

设置:

有一个 JavaFX GUI,用户可以在其中启动各种任务,这些任务本身就是线程任务 ( new Thread(new CustomTask<?>).start();)。这些任务对大约 700k 个 HTTP 请求执行一个循环,并在为数据库准备的插入语句中有大约 10k 个项目时插入处理后的返回值。他们的进度显示在 GUI ( ObservableListitems) 中。

可视化

问题:

这些任务需要很长时间,瓶颈似乎是等待 HTTP 响应时的延迟。(数据库插入是在大量 10k 准备好的插入语句中关闭自动提交的情况下完成的)

目标:

通过将请求放在单独的任务/线程中来提高整体性能。


问题 1:

在这里使用线程是否合理?如何以其他方式提高性能?

问题 2:

如果线程是合理的,我如何实现它?我正在考虑拥有一个全局线程池或ExecutorService请求任务排队的地方。当响应可用时,它将被写入同步列表。如果列表中有 10k+ 个对象,则执行批量插入。

问题 3:

如何确定一个好的线程池大小?如何区分线程?

Thread.activeCount() 返回 7(当前线程组) ManagementFactory.getThreadMXBean().getThreadCount() 返回 13(线程总数?) Runtime.getRuntime().availableProcessors() 返回 8

我读过一些关于多线程的评论,他们都说线程数多于内核数并不一定能提高性能(没有“真正的”并发,时间切片)。我不知道,但如果我不得不猜测,我会说数字 13 包含一些 GUI 线程。我似乎无法理解如何获得 ThreadPoolSize 的有用数字。


我很感激有关如何改进我的应用程序的任何提示。

Ale*_*you 2

当然你可以使用ExecutorService.

\n\n
\n

我\xc2\xb4ve阅读了一些关于多线程的评论,他们都说拥有比核心更多的线程并不一定会提高性能(没有\xe2\x80\x9creal\xe2\x80\x9d并发,时间切片)

\n
\n\n

这对于不睡眠或等待/阻塞的进程来说是正确的,例如计算素数或处理图像。在您的情况下,HTTP 客户端会阻塞,直到响应返回,并且线程保持空闲状态。对于大小为 50-100-200 的 HTTP 请求执行器池是可以的。

\n\n

模式可能如下:

\n\n
ExecutorService es = Executors.newFixedThreadPool(50);\n\n// ...\n// creating request and response future associated with it\nFuture<Response> responseFuture = es.submit(new Callable<Response>() {\n    @Override\n    public Response call() throws Exception {\n        // request data by HTTP\n        return response;\n    }\n});\ncustomTask.push(responseFuture);\n
Run Code Online (Sandbox Code Playgroud)\n\n

在一个customTask对象中,我们创建一个单线程服务执行器,它将在以下列表上运行Responses 列表进行操作:

\n\n
// create single pool executor in order to accept responses \n// one by one and at the order they're requested\nExecutorService customTaskService = Executors.newSingleThreadExecutor(); \nList<Response> results = new ArrayList<>();    \n\n// push() method\npublic void push(final Future<Response> responseFuture) {\n\n     customTaskService.execute(new Runnable() {\n\n         public void run() {\n             try {\n                 // response.get() will block inside this service thread\n                 // though not affecting GUI thread\n                 results.add(response.get(TIMEOUT, TimeUnit.SECONDS)); \n             } catch (RuntimeException e) {\n                 // processing of a request failed\n             }\n             if (results.size() > MAX_SIZE) {\n                 // make inserts to DB\n                 results.clear();\n             }\n         }\n     });\n}   \n
Run Code Online (Sandbox Code Playgroud)\n