我正在编写一个物理模拟软件的想法,其中每个物理元素都将在自己的线程中进行模拟.
这种方法有几个优点.它在概念上非常接近现实世界的运作方式.将系统扩展到多台机器要容易得多.
但是,为了实现这一点,我需要确保所有线程以相同的速度运行,并对"相同"进行相当自由的解释.比如说在彼此的1%之内.
这就是为什么我不一定需要Thread.join()之类的解决方案.我不想要一些超级控制的学校情妇,确保所有线程定期与彼此同步.我只需要能够以大致相同的速度运行线程运行时(无论是Java,Erlang还是其他最适合此问题的运行时).
任何建议都将非常感激.
更新2009-03-16
我要感谢所有回答这个问题的人,特别是那些回答基本上都是"不要这样做"的人.由于每个人的评论,我现在更了解我的问题,而且我不太确定我应该像我原先计划的那样继续.尽管如此,我觉得彼得的答案是问题本身的最佳答案,这也是我接受它的原因.
没有协调你就无法做到这一点.如果一个元素最终需要比另一个元素更便宜的计算(以一种潜在的非显而易见的方式)怎么办?
你不一定需要一个超级控制器 - 你可以在每个线程中保留一些步数计数器,并有一个全局计数器指示"最慢"的线程.(当每个线程完成一些工作时,它必须检查它是否落后于其他线程,如果是这样则更新计数器.)如果一个线程注意到它比最慢的线程要远很多,它可能只是等待一下(可能在监视器上).
只是经常这样做,以避免由于共享数据争用而产生过多的开销,我认为它可以很好地工作.
你需要某种同步.CyclicBarrier类有你需要的:
一种同步辅助工具,允许一组线程全部等待彼此到达公共障碍点.CyclicBarriers在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此.屏障称为循环,因为它可以在等待线程释放后重新使用.
在每个'tick'之后,你可以让所有的线程等待其他的,这些都比较慢.当剩余的线程到达屏障时,它们都将继续.
线程意味着完全独立地运行,这意味着以任何方式同步它们总是很痛苦.在你的情况下,你需要一个中央"时钟",因为没有办法告诉VM每个线程应该获得相同数量的......呃...它应该得到什么?相同数量的RAM?可能没关系.相同数量的CPU?您的所有对象是否都非常相似,每个对象都需要相同数量的汇编指令?
所以我的建议是使用一个中央时钟,向每个进程广播时钟周期.每个进程中的所有线程都读取标记(应该是绝对的),计算它们看到的最后一个标记的差异,然后相应地更新它们的内部模型.
当一个线程完成更新时,它必须让自己进入睡眠状态; 等待下一个打勾.在Java中,对"tick received"锁定使用wait()并使用"notifyAll()"唤醒所有线程.