【问题标题】:How to Multi-threading this example of code?如何对这个代码示例进行多线程处理?
【发布时间】:2011-08-25 14:12:00
【问题描述】:

我想模拟一个分布式系统以及机器如何工作,采用的拓扑是集中式的,我有很多小系统,其中每个子系统都采用这种拓扑,我的意思是我假设我的分布式系统构成许多集中式系统。 我创建了一个简单的离散事件模拟器,它模拟了侧集中系统中的工作,代码如下:

public class SimuleOnesystem { 
// a set of parameters
class Arrival{// here we simulate the arrival of works to a server
 // the code..
}
class Service{// here we simulate the services  }
class Departure{// means that the work is well done
 }
}

我的问题是,我怎样才能多线程这段代码,我的意思是我想同时执行 5 个集中式系统,每个系统都有自己的模拟时钟、事件列表等,这些系统可以通信在发送和接收请求以及执行作业等方面相互之间......

提前致谢。

【问题讨论】:

  • 这个问题太笼统了,你基本上是在要求我们开发你的接口,看看java.lang.Thread,让我们知道什么是不明白的。
  • 将每个模拟包装在 (new Thread() { public void run() { ....... } }).start()?

标签: java multithreading simulation


【解决方案1】:

除了引入线程,正如其他答案中已经指出的那样,您对ring bearer's answer 的评论是正确的:您必须注意事件列表和模拟时钟。。 p>

在我看来,你的例子是一个相当典型的discrete-event simulation。尝试将这些并行化,即使只是跨线程,即在单个地址空间中(由同一台机器上的同一 JVM 执行,可能有多个内核等),并不是一件容易的事。我建议你先阅读一些关于这个问题的介绍性材料(我推荐this book)。

您的基本问题是您无法阻止某些线程比其他线程执行得更快(例如,因为它们必须处理较少的负载),因此它们的本地时钟可能会提前进入模拟的“未来”。如果其他线程之一,即一个落后的线程,现在发出一个新的事件/消息,该事件/消息必须由一个超前的线程处理,那么一切都会中断(或安静地失败并且无效) .想想今天打开你的邮箱,收到了去年的消息,你也应该立即回复……

防止此类情况发生的算法称为同步算法。基本上有两种风格:乐观 方法允许发生这样的落后事件(来自过去的消息),但会检测它们并在必要时清理任何不一致。不过,在您的情况下,最好先查看 conservative 算法,它完全避免使用此类方法。它们(通常)更容易实现,但只有在事件的发送者和事件必须执行的时间之间存在一定的延迟时才能正常工作(例如,有关详细信息,请参阅 this classical paper,或 this more recent one 详细介绍 Java-基于使用保守同步的模拟系统)。 如果您有同步算法,它还将管理您的本地模拟时钟。

由于实现这些算法相当耗时,您也可以考虑使用一些基于 Java 的模拟框架或已经提供方法的库(这是一个众所周知的问题)。

【讨论】:

  • 感谢您的回复,我应该重新考虑一下我的模拟器以防止出现这种情况,但是目前我离这个选项还很远,我目前的问题是如何线程化代码,有没有一种解决方案可以只为一个线程创建局部变量?我的意思是,如何为每个线程创建自己的时钟和事件列表,因为我之前版本的代码不起作用,这个时候我只想同时运行2或3个模拟.....跨度>
  • 这很简单:只需检查如何使用,例如,瑞安在他的回答中提到的 ExecutorService 。线程是一个普通的 Java 对象——如果所有重要的数据结构(时钟等)都是私有成员并且只能在 Thread 的 run() 方法中访问,那么这应该不是问题。顺便说一句,如果您想并行执行一些模拟运行,这称为(模拟)复制 --- 它通常比更细粒度的并行化更容易实现 (因为每个线程都可以独立运行,所以不会遇到上述问题)。
【解决方案2】:

在非常基本的层面上,您所要做的就是将SimuleOnesystem 设为ThreadRunnable - 然后从驱动程序(如main 方法)创建任意数量的线程和start他们。

【讨论】:

  • 是的,我想过这个解决方案,但这并不意味着所有线程都将共享相同的模拟时钟和eventList?我的意思是我希望线程应该是独立的......
  • 除非我错过了什么,不是每个SimuleOnesystem 都使用自己的时钟等吗?除非你让它在全局对象上工作..
【解决方案3】:

我并不是说这是一个轻率的答案,而是:Java Concurrency In Practice,现在就买吧……

但更严重的是,您现在很快就会进入一个非常棘手的测试场景。我不认为你必须使用java.util.concurrent.ExecutorService,但是如果你要在线程之间进行通信,你需要意识到线程安全的通信通道(简单的Lists,@987654324 @s、数据库表等)在每个模拟线程之间。

【讨论】:

    猜你喜欢
    • 2021-07-05
    • 1970-01-01
    • 2020-06-26
    • 2012-07-16
    • 2019-12-30
    • 1970-01-01
    • 2023-03-26
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多