Java如何使用多个内核?

Mun*_*dhi 65 java parallel-processing multithreading

JVM在单个进程中运行,JVM中的线程共享属于该进程的堆.那么JVM如何利用多个内核来提供多个操作系统线程以实现高并发?

Emi*_*mil 27

您可以使用多个线程来使用多个核心.但是使用比机器中存在的核心数量更多的线程可能只是浪费资源.您可以使用availableProcessors()来获取核心数.

Java 7中,有一个fork/join框架可以使用多个内核.

相关问题:

  • 机器通常只有2或4个处理器.您声明"使用比机器中存在的核心数量更多的线程可能只是浪费资源",这是否意味着我们应该只有2到4个线程才能最大限度地提高性能? (5认同)
  • “但是使用比计算机中存在的内核数更多的线程数,只会浪费资源。” 在一般情况下,这没有任何意义。如果您拥有的线程数多于核心数,则这些线程将分布在这些核心中,并像其他任何正在运行的线程/进程一样,获得它们在给定核心中的份额,从而使进程取得进展,这肯定比做线程更有效。按顺序工作。 (2认同)

Ste*_*e-o 19

Java 1.2中的本机线程替换了绿色线程.

  • +1 - 换句话说,操作系统将根据系统调度和资源管理约束安排使用不同内核的不同Java线程. (3认同)

Vij*_*hew 18

如果操作系统通过可用处理器分配线程,Java将受益于多个内核.JVM本身并没有做任何特别的事情来让它的线程在多个核心上均匀地进行调度.要记住以下几点:

  • 在实现并行算法时,最好是生成与核心一样多的线程.(Runtime.getRuntime().availableProcessors()).不是更多,而不是更少.
  • 使用java.util.concurrent套餐提供的设施.
  • 确保您的个人库中具有Java Concurrency in Practice.

  • 不多也不少。不正确。根据您建议的书,应该产生一个(处理器数+ 1),因为当某些线程正在执行 IO 时,额外的线程可以利用空闲 CPU (2认同)
  • 线程只是在做一些处理,而不是在等待任何远程调用(例如数据库,远程API,JMS等),因此上述建议很有意义。但是实际上,所有常规应用程序都使用远程调用。因此,最佳线程数可以根据远程调用的延迟而有所不同。做负载测试并决定。 (2认同)

Gra*_*ray 18

JVM在单个进程中运行,JVM中的线程共享属于该进程的堆.那么JVM如何利用多个内核来提供多个操作系统线程以实现高并发?

如果在多CPU机器上运行,Java将利用底层操作系统的线程来执行在不同CPU上执行代码的实际工作.当每个Java线程启动时,它会创建一个相关的OS线程和OS负责调度等.JVM的某些做一些管理和线程和Java语言结构,如跟踪volatile,synchronized,notify(),wait(),等所有影响运行OS线程的状态.

JVM在单个进程中运行,JVM中的线程共享属于该进程的堆.

JVM不必"在单个进程中运行",因为即使垃圾收集器和其他JVM代码也在不同的线程中运行,并且操作系统通常将这些不同的线程表示为不同的进程.例如,在Linux中,您在进程列表中看到的单个进程通常伪装成一堆不同的线程进程.即使您使用的是单核计算机,也是如此.

但是,你是正确的,他们都共享相同的堆空间.它们实际上共享相同的整个内存空间,这意味着代码,实习字符串,堆栈空间等.

那么JVM如何利用多个内核来提供多个操作系统线程以实现高并发?

线程从几个方面得到了性能提升.显然,直接并发通常会使程序运行得更快.能够同时执行多个CPU任务可以(但不总是)提高应用程序的吞吐量.您还可以将IO操作隔离到单个线程,这意味着当线程在IO上等待(读/写磁盘/网络等)时,其他线程可以正在运行.

但就内存而言,由于本地每CPU缓存内存,线程可以获得很多性能提升.当线程在CPU上运行时,CPU的本地高速内存高速缓存可帮助线程在本地隔离存储请求,而无需花时间读取或写入中央内存.这就是为什么volatilesynchronized调用包括内存同步结构的原因,因为当线程需要协调其工作或相互通信时,必须将高速缓存存储器刷新到主存储器或使其无效.

  • @NikiHerl 这里的重点是 Java 线程具有操作系统线程等效项。如果我没有指定线程的类型,那么没关系。例如,当我谈论将 IO 隔离到单个线程时,即针对 JVM 线程和正在执行工作的操作系统线程。 (2认同)