ActiveObject模式:

ActiveObject模式和Command模式的配合使用是实现多线程控制的一项古老的技术,该模式有多种使用方式,为许多工业系统提供了一个简单的多任务核心。

// 活动对象的工具类,封装添加命令的方法以及运行方法

class ActiveObjectEngine
{
ArrayList itsCommands = new ArrayList();
// 添加命令 //
public void AddCommand(Command c)
{
itsCommands.Add(c);
}
// 运行命令,并且移除 //
public void Run()
{
while (itsCommands.Count > )
{
Command c = (Command)itsCommands[];
itsCommands.RemoveAt();
c.Execute();
}
}
}

Run()函数只是遍历列表,执行并移除每个命令。如此,似乎也没给人很深刻的印象,但是发挥一下想象,如果链表中的command对象会克隆自己并把克隆对象放到链表的尾部,会是什么情况?可见这个链表不会为空,Run()永远不会返回。

// 唤醒命令,类似于undo()函数 //
class WakeUpCommand : Command
{
public bool executed = false;
public void Execute()
{
executed = true;
}
}
// 睡眠命令 //
class SleepCommand : Command
{
private Command wakeupCommand = null;
private ActiveObjectEngine engine = null;
private long sleepTime = ;
private System.DateTime startTime;
private bool started = false; public SleepCommand(long milliseconds, ActiveObjectEngine e,Command wakeupCommand)
{
sleepTime = milliseconds;
engine = e;
this.wakeupCommand = wakeupCommand;
}
public void Execute()
{
System.DateTime current = DateTime.Now;
if (!started)
{
Debug.Log("one..................add this");
started = true;
startTime = current;
engine.AddCommand(this);
}
else
{
TimeSpan elapsedTime = current - startTime;
Debug.Log("__" + elapsedTime.TotalMilliseconds);
if (elapsedTime.TotalMilliseconds < sleepTime)
{
engine.AddCommand(this);
Debug.Log("..................add this");
}
else
{
engine.AddCommand(wakeupCommand);
Debug.Log("..................add wakeup");
}
}
}
}

可见它的构造方法有三个参数,第一个是延迟时间,第二个是活动对象的工具类,第三个是唤醒命令类,分析代码可以看出,当前时间小于延迟时间的时候,会重复的调用自身(sleepCommand)的excute(),当大于延迟时间,就调用wakeupCommand,表示任务处理结束。

然后调用以上代码:

// 这里测试环境是unity3d,所以会看到Start()函数
void Start () {
WakeUpCommand wakeup = new WakeUpCommand();
ActiveObjectEngine e = new ActiveObjectEngine();
SleepCommand c = new SleepCommand(, e, wakeup);
e.AddCommand(c);
DateTime start = DateTime.Now;
e.Run(); DateTime stop = DateTime.Now;
TimeSpan sleepTime = stop - start; print("command end:" + wakeup.executed + " run time:" + sleepTime.TotalMilliseconds);
}

打印的结果,wakeup.executed : true, 运行时间是一个大于900毫秒的数。

我们可以将该程序和等待一个事件的多线程程序做一个对比,多线程程序等待的时候,通常是使用操作系统调用来阻塞自己直到事件发生。

而上面的代码并没有阻塞,采用该技术的变体实现多线程是一个很优秀的方式,这种类型的线程称为run-to-completion任务(RTC),它的优点就是共享同一个运行时栈。这在需要大量线程的内存受限系统中是一个强大的优势。

以下代码是一个多线程的实例

class DelayedTyper : Command
{
private long itsDelay;
private char itsChar;
private static bool stop = false;
private static ActiveObjectEngine engine = new ActiveObjectEngine(); class StopCommand : Command
{
public void Execute()
{
DelayedTyper.stop = true;
}
}
public DelayedTyper(long delay, char c)
{
itsDelay = delay;
itsChar = c;
} public void Execute()
{
Debug.Log(itsChar);
if (!stop)
{
DelayAndRepeat();
}
}
public void DelayAndRepeat()
{
engine.AddCommand(new SleepCommand(itsDelay, engine, this));
} public static void Go()
{
engine.AddCommand(new DelayedTyper(, ''));
engine.AddCommand(new DelayedTyper(, ''));
engine.AddCommand(new DelayedTyper(, ''));
engine.AddCommand(new DelayedTyper(, '')); Command stopCommand = new StopCommand();
engine.AddCommand(new SleepCommand(, engine, stopCommand));
engine.Run();
}
}

在Start函数添加:

DelayedTyper.Go();

打印的结果可以看出,每次的都会不一样,这是因为CPU的时钟和实时时钟没有完美的同步,这种不确定的行为不就是多线程系统的特点么。

最新文章

  1. ASP.NET MVC载入页面常用方法
  2. .NET 微信Token验证和消息接收和回复
  3. 帝国cms实现会员注册之后根据所在会员组转向的方法
  4. ThinkPHP讲解(十)——第三方类的引入:以分页为主
  5. 《J2EE,J2SE,J2ME》
  6. hdu 5203
  7. jquery加载页面的方法(页面加载完成就执行)
  8. shark错误:Query returned non-zero code: -101
  9. 数据绑定(八)使用Binding的RelativeSource
  10. 打开WEBBROWSER的选中文件路径
  11. FZU 2102 Solve equation(水,进制转化)&amp;&amp; FZU 2111(贪心,交换使数字最小)
  12. 开始 space viking 之旅
  13. 201521123116 《java程序设计》第十三周学习总结
  14. 一个&quot;.java&quot;源文件中是否可以包括多个类
  15. 64bit program invoke 32bit library with rpcgen
  16. 爬虫-----爬取所有国家的首都、面积 ,并保存到txt文件中
  17. Windows网络发现无法启动
  18. docker 私有仓库之Harbor搭建与使用
  19. 从C,C++,JAVA和C#看String库的发展(一)----C语言和C++篇
  20. Hive格式各种格式下不同压缩算法的比较

热门文章

  1. Java设计模式10:设计模式之 值对象
  2. php笔记03:布尔类型,字符串,浮点数
  3. 西门子PLC两线制,四线制
  4. ios 界面间跳转方法总结
  5. failed to obtain a cell from its dataSource
  6. 关于Eclipse中配置产品启动的插件
  7. 关于MapReduce
  8. Java序列化接口的作用总结
  9. 电脑小白自学软件编程-.Net语法基础之循环语句,纯技巧干货
  10. JavaScript入门(10)