Java并发:用很少的线程执行许多"无限"任务

met*_*ori 10 java concurrency executors

我正在为一组N粒子构建一个(并发)模拟器,这些粒子根据牛顿定律在空间中移动.我的想法是将每个粒子建模为一个任务,它与其他粒子(任务)相互作用,以获得它们的位置和质量,以便计算它所受的净力.每个粒子任务都是如此

while(true){
   force = thisParticle.calculateNetForce(allTheParticles);
   thisParticle.waitForAllTheParticlesToCalculateNetForce(); // synchronization
   thisParticle.updatePosition(force);
   thisParticle.waitForAllTheParticlesToUpdateTheirState(); // synchronization
}
Run Code Online (Sandbox Code Playgroud)

我可以拥有大量粒子(100或更多),因此我无法创建如此多的Java线程(映射到物理线程).我的想法是使用Runtime.getRuntime().availableProcessors()+1可以执行许多任务的线程.

但是,我不能使用FixedThreadExecutor,因为粒子任务不会结束.我想使用FixedThreadExecutor,它必须也能够在内部执行某种调度.你知道为此目的吗?

或者,您是否可以通过并发的角度(例如,不同的任务分解)向我建议更好的方法来建模这样的系统?

Ps:我仅限于"经典"并发机制,不包括演员或类似的架构.

Pet*_*rey 5

性能的最大杀手可能是您执行的线程安全检查,以确保所有粒子以线程安全的方式进行交互.我建议你每个核心使用一个线程,并尽量减少线程之间的交互.这可以通过将空间划分为线程来完成,例如半个X,一半Y,一半Z将空间划分为8.您可以同时独立地查看每个空间中的所有交互,并且只需要担心粒子从一个空间传递空格/线程到另一个.


Joh*_*int 3

我假设您将所有粒子存储在二维数组的数组中?这将是Fork-Join 框架的一个很好的候选者。

您可以将数组部分的计算分成更小的部分。你不断地分裂,直到达到一定的大小。最后计算并返回。然后返回的值将与树的另一侧连接并计算。