FSP语言学习(四):对多线程程序建模

在Java程序中,当一个以上的线程是活的时,就会出现并发现象。如果一个线程已经启动但尚未终止,它就是活的。在本篇博客,我们将介绍一个简单的Java多线程程序的例子,除了每个Java程序中的主执行线程外,还有两个并发的活动线程。示例程序中的线程并不直接互动。关于线程如何交互的话题将留到后面讨论。

2. ThreadDemo Example – Model

该示例程序驱动如图中描述:

每个线程,A和B,都可以通过按下适当的按钮来运行和暂停。当一个线程运行时,与之相关的显示器会旋转。当线程暂停时,旋转停止。当一个线程暂停时,其背景颜色被设置为红色,当它运行时,背景颜色被设置为绿色。线程之间不相互影响,但是当按钮被按下时,它们与执行的Java主线程相互影响。

小程序中的两个线程的行为由以下ROTATOR过程来模拟。

ROTATOR = PAUSED,
PAUSED  = (run->RUN | pause->PAUSED),
RUN     = (pause->PAUSED |{run,rotate}->RUN).

流程在进入RUN状态之前不能执行旋转动作。这只能在运行动作之后发生,运行动作是指按下运行按钮。当暂停动作发生时——模拟暂停按钮——进程移回暂停状态,在该状态下,旋转动作不能发生。该模型意味着ROTATOR的实现永远运行——没有办法停止它。对永远运行的线程进行编程并不是好的做法;当例如浏览器调用Applet.stop()方法时,它们应该有秩序地终止。Java的设计者不建议使用Thread.stop()来终止一个线程的执行。相反,他们建议使用Thread.interrupt(),该方法会引发InterruptedException,允许线程在终止之前进行清理。我们可以在ROTATOR进程中加入终止,如下图所示。

ROTATOR = PAUSED,
PAUSED  = (run->RUN |pause->PAUSED
          |interrupt->STOP),
RUN     = (pause->PAUSED |{run,rotate}->RUN
          |interrupt->STOP).

我们将a.interrupt和b.interrupt动作重新标记为同一个动作stop,表明当浏览器调用Applet.stop()时,我们总是同时中断两个线程。构建好模型后,我们可以使用LTSA工具将其动画化,以检查其行为是否与我们期望的ThreadDemo小程序的行为相一致。下图是LTSA Animator窗口的屏幕截图。那些可以选择执行的动作被打上了勾。在图中,动作a.run使进程a处于可以发生a.rotate动作的状态,而进程b不能执行b.rotate动作,因为b.run还没有发生。

事实上,在实现中,环境是由Java程序的执行主线程提供的。当然,我们也可以将这个主线程建模为一个分享动作的进程。显示器可以在任何时候旋转,按钮可以在任何时候被按下。因此,这个主线程可以被建模为。

MAIN = ({a.rotate,a.run,a.pause,stop,
         b.rotate,b.run,b.pause}->MAIN).

用THREAD_DEMO组成MAIN并不修改THREAD_DEMO的行为,因为它没有对动作提供任何额外的排序约束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值