如何对这个代码示例进行多线程处理?
我想模拟一个分布式系统以及机器如何工作,采用的拓扑是集中式拓扑,我有很多小系统,其中每个子系统都采用这种拓扑,我的意思是我假设我的分布式系统由许多集中式系统组成。 我创建了一个简单的离散事件模拟器,它模拟了一个集中式系统中的工作,代码如下:
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个集中式系统每个系统都有自己的模拟时钟,事件列表等,并且这些系统可以在发送和接收请求以及执行作业等方面相互通信......
提前致谢。
I would like to simulate a distributed system and how machines do their works, the topology adopted is a centralized one, I have many little systems in which each sub systems adopts this topology, I mean I suppose that my distributed system constitutes of many centralized systems.
I have created a simple discrete event simulator, which simulates the work in side One centralized system, the code is like:
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
}
}
My question is, how could I multithreaded this code, I mean I would like to execute for example 5 Centralized systems at the same time in which each system has its own simulation clock, eventList and so on, and these systems can communicate between each other in term of sending and receiving request and executing jobs etc...
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除了引入线程之外,正如其他答案中已经指出的那样,您对 戒指持有者的回答是正确的:你必须照顾好事件列表和模拟时钟。
据我所知,您的示例是一个相当典型的离散事件模拟。尝试并行化这些,即使只是跨线程,即在单个地址空间中(由单个机器上的同一 JVM 执行,可能有多个核心等),也不是很简单。我建议您首先阅读一些有关此事的介绍性材料(我建议这本书)。
您的基本问题是,您无法阻止某些线程比其他线程执行得更快(例如,因为它们必须处理更少的负载),因此它们的本地时钟可能会提前到模拟的“未来”。如果其他线程之一(即落后的线程)现在发出一个新的事件/消息,该事件/消息必须由提前太远的一个线程处理,则一切都会中断(或安静地失败并无效) 。想象一下今天打开你的邮箱并收到去年的一条消息,你也应该立即回复......
防止这种情况发生的算法称为同步算法。这些基本上有两种风格:乐观方法允许此类落后事件(来自过去的消息)发生,但检测它们并在必要时清除任何不一致的情况。不过,就您而言,似乎建议首先查看保守算法,这些算法完全避免使用此类方法。它们(通常)更容易实现,但只有在事件发送者和事件执行时间之间存在一定延迟时才能正常工作(例如,请参阅 这篇经典论文详细信息,或最近的一个,详细介绍了一个基于 Java 的模拟系统,该系统使用保守同步)。
如果您有同步算法,它还将管理您的本地模拟时钟。
由于实现这些算法相当耗时,您也可以考虑使用一些基于Java的模拟框架或已经提供方法的库(这是一个众所周知的问题)。
Besides the introduction of threads, as already pointed out in the other answers, your comment to ring bearer's answer is true: you have to take care of the event list and the simulation clock.
As far as I can see it, your example is a fairly typical discrete-event simulation. Trying to parallelize those, even just across threads, i.e. in a single address space (executed by the same JVM on a single machine, which may have multiple cores etc.), is not quite trivial. I would suggest you start with reading some introductory material on the matter (I would recommend this book).
Your basic problem is that you cannot prevent some threads of executing faster than others (e.g. because they have to handle less load), and hence their local clocks may advance into the simulated 'future'. If one of the other threads, i.e. a thread that is lagging behind, now issues a new event/message that would have to be processed by one thread that is advanced too far in time, everything will break (or fail quietly and be invalid). Think of opening your mailbox today and receiving a message from last year, to which you also should have responded immediately...
Algorithms that prevent such situations from happening are called synchronization algorithms. There are basically two flavors of those: optimistic methods allows such straggler events (messages from the past) to happen, but detect them and clean up any inconsistencies if necessary. In your case, though, it seems advisable to look at conservative algorithms first, which avoid such methods altogether. They are (usually) easier to implement, but only work well if there are certain delays between the sender of an event and the time the event has to be executed (e.g. see this classical paper for details, or this more recent one detailing a Java-based simulation system that uses conservative synchronization).
If you have a synchronization algorithm in place, it will also manage your local simulation time clocks.
As implementing these algorithms is rather time-consuming, you may also consider to use some Java-based simulation framework or library that already provides the methods (it's a well-known problem).
在非常基础的层面上,您所要做的就是使
SimuleOnesystem
成为Thread
或Runnable
- 然后从驱动程序(例如main
方法,创建任意数量的线程并启动
它们。At a very basic level, all you have to do is to make
SimuleOnesystem
aThread
or aRunnable
- then from a driver program such as amain
method, create as many threads as you like andstart
them.我并不是说这是一个轻率的答案,而是:Java 并发实践,立即购买...
但更严重的是,您现在很快就进入了一个非常棘手的测试场景。我不认为您必须使用 java.util.concurrent.ExecutorService,但是如果您要在线程之间进行通信,您需要意识到线程安全每个模拟线程之间的通信通道(简单的列表、消息队列、数据库表等)。
I don't mean this as a flippant answer, but: Java Concurrency In Practice, buy it now...
But to be more serious, you are now quickly getting into a very hairy testing scenario. I don't believe that you are going to have to get into using
java.util.concurrent.ExecutorService
, but if you are going to communicate between threads, you need to be conscious of having thread-safe communication channels (simpleList
s,MessageQueue
s, database tables, etc...) between each simulation thread.