编辑: 静看花开花落 | 2018-09-24 |
2 这样的返回能被一个无标注的箭头所显示 从 激活 的底部返回调用者的 生命线 在异步消息的情 况下 一个 激活 的结束不隐含一个返回 这记号是非常直观的 连接对象的生命期是显而易见的 象这样一些事物是很难在协作图 中表示清楚的 异步消息和并行 注意一下图
3 中一些箭头的头部是不完整的 这 半箭头 标注了异步消息 异步消息是 一种在接收对象中产生一条新执行线后就立即返回的消息
3 连接消息 例如 立即返回到 蜂窝式无线电话台 对象 然而 你能看到在 连接 对象的 生命线 上的 激活 框 那么连接方法仍在继续执行 这连接方法正在一个分离的线程中执行 这演示了顺序图具有 显示并发 多线程交互的能力 在协作图中描述这种信息就要笨拙的多 :拨号器 :蜂窝式无线电话 台 :连接 连接 pno 创建对象 连接 pno 连接建立 结束 断开连接 连接断开 对象销毁 图3连接和断开连接 竞争条件 有并行的地方就可能存在竞争条件 竞争条件出现在一个单线程或对象收到来至两个竞争 源的消息 如果处理不好 参与对象可能被弄糊涂 考虑图
4 我们又看到两个顺序图 在这两个图中为了清晰 已将 激活 框忽略
4 第一个图显示 了正常的事件过程 当一个蜂窝电话收到一个呼叫 蜂窝式无线电话台对象检测收到的呼叫 并响铃 同时也告诉拨号器对象有一个呼叫正过来 这使得拨号器对象处在一个特殊的状态 当拨号器对象处在这特殊状态时按下发送按钮 那么拨号器对象向蜂窝式无线电话台对象发 应答消息 因此呼叫被连接
3 事实上并不需要产生新的线程 所需要的是接收对象在一个分离的线程中执行方法 这线程可能存在于 异步消息到来之前 而仅仅是等待着做一些事
4 UML 允许设计者根据判断进行这样的忽略 为什么需要特殊状态 回头看一下图
1 你能看到拨号器对象能接收发送消息 在用户输 入电话号码后 因此有两种情况 哪一种情况下拨号器接收发送消息 一是当呼叫时 还有 当应答时 当呼叫时 拨号器送连接消息到蜂窝式无线电话台 当应答时 拨号器送应答消 息到蜂窝式无线电话台 这第二个顺序图显示了竞争条件 在这种情况用户正在拨号 一个呼叫进入蜂窝式无线电 话台对象 正在这时用户按下了发送按钮发出一个呼叫 这进入的呼叫消息和连接消息交叉 而过 消息的交叉显示了竞争 当一个消息向下倾斜象这两个一样 表示在消息的发送和消息的接收之间有一段时间差 在系统中 消息通过网络 很显然消息需要时间来传递 或在队列中等待被接收 在多线程 应用中 对象间的消息经常被转换成消息对象等待在队列中 因此 大量的时间可能化在消 息的发送 队列 和它们的最终接收和执行中 明显的 如果蜂窝式无线电话台对象不曾被写下期望事件的返回 它将被搞糊涂 有可能 设计蜂窝式无线电话台对象的状态机的工程师不曾期望到一个连接消息将被接收在它刚刚 送出 收到呼叫 消息后 :发送按钮适配器 :拨号器 :蜂窝式无线电话 台 :响铃器 发送 收到呼叫 应答 响铃 :发送按钮适配器 :拨号器 :蜂窝式无线电话 台 :响铃器 发送 收到呼叫 连接 号码 响铃 图4竞争条件在拨号和应答之间 象这样的竞争条件是一种重要的错误来源在并发系统中 调试它们可能是非常困难 因为 它们依赖几个事件的精确定时 这些问题导致 间歇的不可解释和不可重复的崩溃 这是 所有时实软件工程师的祸端 带倾斜箭头的顺序图5 是一种很好的工具 用来发现哪里会出 现竞争条件 结论