I'm building a (concurrent) simulator for a set of N particles that are moving in a space according to the Newton's laws. My idea is model each particle as a task, which interacts with other particles (tasks) in order to get their positions and masses in order to calculate the net force it is subject to. Each particle-task is something as
while(true){
force = thisParticle.calculateNetForce(allTheParticles);
thisParticle.waitForAllTheParticlesToCalculateNetForce(); // synchronization
thisParticle.updatePosition(force);
thisParticle.waitForAllTheParticlesToUpdateTheirState(); // synchronization
}
I can have a lot of particles (100 or more), so I can't create such a number of Java threads (which are mapped to physical threads).
My idea is to use Runtime.getRuntime().availableProcessors()+1
threads onto which the many tasks can be executed.
However, I can't use a FixedThreadExecutor because the particle-tasks does not end. I would like to use a FixedThreadExecutor which must be also able to perform a sort of scheduling internally. Do you know something for this purpose?
Or, could you suggest me better approaches for modelling such a system by a point of view of concurrency (e.g. a different task decomposition) ?
P.s.: I am limited to "classical" concurrency mechanisms, not including actors or similar architectures.
The simplest way to avoid problems with concurrency is to share only immutable data between threads. Immutable data is data which cannot be changed. To make a class immutable define the class and all its fields as final. Also ensure that no reference to fields escape during construction.
While Java isn't necessarily the best language for concurrency, there are a lot of tools, libraries, documentation and best practices out there to help. Using message passing and immutability instead of threads and shared state is considered the better approach to programming concurrent applications.
The biggest killer for performance is likely to be the thread safety checks you perform to ensure all the particles are interacting in a thread safe manner. I suggest you use one thread per core and try to minimise the interaction between threads. This can be done by dividing your space into threads e.g. half X, half Y, half Z divides the space into 8. You cal look at all the interactions in each space concurrently and independently and you only need to worry when a particle passed from one space/thread to another.
I would assume you are storing all your particles in maybe an array of 2-dimensiional array? This would be a great candidate for the Fork-Join Framework.
You would split the calculation of portions of the array into smaller portions. You keep splitting until at a certain size. Finally you calculate and return. The returned value will then be joined and calculated with other the other side of the tree.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With