了解Java并发

问题描述 投票:0回答:1

我正在底层学习 Java 并发,并且阅读了一些有关多线程和并发的 Java 文章和视频,但似乎无法将它们全部放在一起

这是我到目前为止所理解的要点(如果我错了,请纠正我!):

  1. CPU有物理核心和逻辑核心。逻辑核心本质上就是物理核心*每个核心可以运行的线程数
  2. Java 有一个“每线程请求”模型,因此每个请求将占用其中 1 个逻辑核心
  3. 因此,如果 cpu 有 8 个逻辑核心,jvm 可以并行运行 8 个进程(不是并发!)
  4. 并发是指单个逻辑核心可以处理多个请求的过程,假设一个请求将进行阻塞I/O调用,而不是等待I/O调用,则线程可以被释放以用于处理另一个请求。这就是并发的意思

考虑到这一切

现在我想这就是令人困惑的地方 假设我有8个逻辑核心,和一个可以接收api调用的spring web mvc服务器。在这个 api 调用中,我们将执行一个永无止境的阻塞 I/O 操作 这是不是意味着

  1. 由于所有线程都已使用,所以在另一个请求排队/延迟之前我最多只能命中 8 次?

下一个将是对spring web mvc的改进,我希望以非阻塞的方式进行I/O操作,而不是在主线程上进行I/O操作。这意味着我将为每个 api 调用生成一个新线程。这是不是意味着

  1. 由于所有线程都已使用,所以在另一个请求排队/延迟之前我最多只能命中 4 次? (4 个主线程,4 个来自阻塞 I/O 调用)

更进一步,我现在将使用 CompletableFuture / Future,以便它是异步且非阻塞的,而不是以阻塞方式在新线程上进行 I/O 调用。

x = CompletableFuture.supplyAsync(() -> {
    // Long I/O call 
})
// do some operation
x.join();

我的问题是

  1. 在 SupplyAsync 部分之后,该过程将继续,直到我们来到 x.join();在等待 x.join() 时,线程会阻塞吗?或者线程是否会被释放并且上下文切换会发生,以便该线程可以用于服务另一个请求?

如果问题3的答案是线程将被阻塞,这是否意味着与

new thread I/O blocking call
(参考第二个改进)的唯一区别是,当我们使用completableFuture时,我们可以在阻塞之前
// do some operation
打电话?

对于问题 3,我假设一旦我们到达代码的阻塞部分(.get() for Future / .join() completableFuture),线程将被释放并可以处理另一个请求。

注意:抱歉我的英语不好!

java future completable-future java.util.concurrent
1个回答
0
投票

线程并不意味着它们会在每个核心上运行。

© www.soinside.com 2019 - 2024. All rights reserved.