常见的多线程实现是使用某个类,其中Method_A()
在线程中运行,并且处于阻塞状态,等待某些信号/事件成员变量(例如WaitForSingleObject
)。
在不同线程中运行的交互类将随后调用Method_B()
,它可以完成一些工作,设置信号/事件变量,也许还要执行更多工作,然后返回。
我如何在序列图上表示这种相互作用?
我是否应该有两条生命线,即使每个线程都在类的同一实例上运行,每个线程也要一条生命线?我的建模工具(Enterprise Architect 12)不允许同一个类在序列图上出现两次,因此不鼓励这样做。
编辑:Geert指出,序列图应使用实例,而不是类,这是一个合理的注释。但是问题是相同的:多个生命线将意味着多个实例,但是问题Method_A()
和Method_B()
在 same 实例上运行,只是来自不同的线程。怎么表示呢?
答案 0 :(得分:2)
(编辑您可以通过使用@sim指出的异步消息来解决此问题。这样做就可以了。下面的答案显示了幕后发生的事情。不在乎细节,请给出答案。)
您要问的是更多的设计,而不是UML问题。即,并发实例如何相互通信。你先说
Method_A()正在线程中运行,并且处于阻塞等待状态
仅仅意味着它由于被阻止而不能接受任何东西。现在,从您的问题的上下文中猜测,我假设您仍然要与该实例进行通信,因为
然后在其他线程中调用Method_B()
因此,为了能够接受消息,实例必须处于适当的状态。有两种方法可以实现这一目标。一个简单的方法是,如果相应的操作系统对此提供支持,则返回调度程序并告诉他它正在等待某些消息。
现在,当调用method_b
时,您会在Object1
内知道自己在method_a
内处于某种空闲状态,并执行适当的(返回)操作。
另一种方法是轮询调度程序以获取传入消息并处理它们。
您需要记住,发送消息通常不会直接处理实例,而是会告诉系统调度程序与适当的实例进行交互(至少在大多数OS中如此)。
我只是从Modula2编译器中记得我曾经写过它具有协程的概念,该协程允许并发线程在已编译的代码中运行。但是基本上,这只是映射到在一个半单线程的引擎盖下运行的两个独立线程,并且在进行详细介绍时会用两条生命线来描述它。
N.B .:它应该是操作而不是方法(因为它是由消息调用的;而方法是在操作内部实现的)。并且按照惯例,它们应该以小写字符开头。
还有:不要在SD中使用类。不幸的是,EA仍然允许这样做(为什么?问他们!)。在他们的文档中某个地方隐藏着一个句子,您必须使用实例。否则,模型将崩溃。 SD始终是(!)互相交谈的实例序列的样本。类不会说话,它们只是实例的蓝图。
答案 1 :(得分:1)
永远不要在序列图中使用类,而应使用将类作为分类器的实例/生命线。
如果在将类拖到序列图时按住控件,则可以选择将其作为实例而不是作为类。
通过这种方式,您可以为同一个班级添加任意数量的
。答案 2 :(得分:1)
您要查找的符号是异步消息。从理论上讲,您可以使用一条生命线来表达这一点。但这是不可读的。因此,可能在您的类中有一个线程类的两个实例,并显示这些实例之间的交互。但是永远不要在序列图中显示类。 但是,为什么要使用序列图呢?对于这种内部行为,活动图最可能更合适。在那里,您可以使用发送和接收消息元素来表达每个线程的行为。或者,如果将其显示在一个图中,则可以使用fork。
答案 3 :(得分:1)