Java - 线程和CPU之间的关系

时间:2012-12-13 18:28:33

标签: java multithreading executorservice threadpool

我是多线程的新手,我正在开发一个项目,我试图在我的Java程序中使用4个CPU。我想做一些像

这样的事情
int numProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService e = Executors.newFixedThreadPool(numProcessors);

这可以保证每个CPU都有一个线程吗?在我创建线程时,系统不会很忙,但是一段时间后它会非常繁忙。我认为操作系统会选择最不繁忙的CPU来创建线程,但是如果它们在创建时没有特别繁忙的话,它是如何工作的?

此外,线程池服务应该重用线程,但如果它看到另一个CPU上有更多可用性,它会杀死线程并在那里产生一个新线程吗?

3 个答案:

答案 0 :(得分:2)

不,它不能保证线程运行的位置

实际上,OS线程调度程序可以在它认为合适的情况下自由地在核心周围迁移线程(因此,您可以在核心0上使用一行,在核心4上使用下一行)

你可以设置线程的affinity但这在java中不可用(AFAIK)

答案 1 :(得分:2)

  

这可以保证每个CPU都有一个线程吗?

如果你有四个需要同时执行的任务,你可以期望它们各有一个线程。在HotSpot JVM中,它创建Thread对象,它是创建池时实际线程的代理。创建实际线程时,以及如何对您起作用。

  

在我创建线程时,系统不会很忙,但是一段时间之后它会非常繁忙。我认为操作系统会选择最不繁忙的CPU来创建线程,但是如果它们在创建时没有特别繁忙的话,它是如何工作的?

线程由操作系统创建,并添加到要安排的线程列表中。

  

此外,线程池服务应该重用线程,但如果它看到另一个CPU上有更多可用性,它会杀死线程并在那里产生一个新线程吗?

Java在这件事上没有发言权。操作系统决定。它不会杀死并重新启动线程。

线程与您建议的方式不依赖于CPU。操作系统根据需要运行的线程和哪些CPU是空闲的,在CPU之间传递线程。

答案 2 :(得分:1)

“如果它看到另一个CPU上有更多可用性,它会杀死该线程并在那里产生一个新线程吗?”

没有必要杀死并产生另一个来使用可用的CPU。线程是未绑定到特定CPU的内存对象,可以从一个CPU浮动到另一个CPU。线程执行是这样的循环:

  • Thread.start()将线程放入处理器队列
  • 当有可用处理器时,调度程序将处理器队列中的第一个线程置于处理器上
  • 当线程阻塞占用的锁,或者正在等待I / O操作结束时,它将从处理器中取出并放入相应的队列中。释放锁定或I / O操作完成后,线程将从该队列移回处理器队列。
  • 当线程工作太长而没有阻塞(o / s依赖时间,比如50 ms)时,会发生中断,并且调度程序会查看处理器队列中是否有线程。如果存在,则当前线程从处理器中取出并放在处理器队列的末尾,并将队列中的第一个线程放在处理器上。这样,长时间运行的线程也允许其他线程执行。

因此,线程经常改变它们的状态,但这对程序员来说是透明的。线程的整体思想是线程是处理器的模型,比真正的处理器更方便。使用该模型并且不必担心在处理器上映射线程,直到您真正需要。