请选择 进入手机版 | 继续访问电脑版

技术控

    今日:47| 主题:53603
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] 编程思想之消息机制

[复制链接]
morpheus 发表于 2016-10-6 08:42:29
187 6

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
从一个剧情开始

  路遥的《平凡的世界》因为翻拍成电视剧,又再次火起来了!我们就从这里开始吧,其小说是以这样一个场景开头的:
  在一个半山腰县立高中的大院坝里,在一个校园内的南墙根下,按班级排起了十几个纵队的年轻男女,各班的值日生正忙碌地给众人分发饭菜…… 菜分为甲、乙、丙三等,甲菜以土豆、白菜、粉条为主,还有可人大肉片,乙菜没有肉,丙菜只有清水煮白萝卜。主食也分为三等:白面馍,玉米面馍,高粱面馍,白、黄、黑分别代表了三种差别,学生们戏称欧洲、亚洲、非洲。每个人的饭菜都是昨天登记好并付了饭票的,在这一长长的队伍中自然以光景较好的富家子弟排在最前,光景一般的随后,而那些家庭贫困少吃缺穿的学生只能在其他学生走后才姗姗来迟……
         

编程思想之消息机制

编程思想之消息机制
         

编程思想之消息机制

编程思想之消息机制
    这一活生生的例子虽然看着有些悲凉(排队打饭的情景相信曾经是学生的你一定经历过,可能没这般悲凉而已),却像极了消息机制的原理,也许发明消息机制的灵感就是原来于这样的生活吧!排队的学生就是消息队列,值日生分发饭菜就消息循环并完成消息处理,学生吃饭就类似于事件处理。
  什么是消息?

  何为消息?消息就是带有某种信息的信号,如你用鼠标点击一个窗口会产生鼠标的消息,键盘输入字符会产生键盘的消息,一个窗口大小的改变也会产生消息。
  消息从何而来?根据冯·诺依曼的体系结构计算机有运算器、存储器、控制器和输入设备和输出设备五大部件组成,消息主要来自输入设备,如键盘、鼠标、扫描仪等,也可来自已窗口和操作系统。
  消息机制的三大要点:消息队列、消息循环(分发)、消息处理。其结构如下:
         

编程思想之消息机制

编程思想之消息机制
         图 1 :消息机制原理      消息队列就是存放消息的一种队列,具有先进先出的特点。每产生一个消息都会添加进消息队列中,在Window中消息队列是在操作系统中定义的。消息队列就如同一群排队打饭的少男少女,这群人中光景较好的排在前面,光景较差的排在后面,可以理解成是一种优先级队列!要想更多的了解队列的相关知识,可参见队列。
    消息循环就是通过循环(如while)不断地从消息队列中取得队首的消息,并将消息分发出去。类似于上面的例子中分发饭菜值日生。
    消息处理就是在接收到消息之后根据不同的消息类型做出不同的处理。上面例子中值日生根据学生不同类型的饭票给他们不同等级的饭菜就是消息处理,学生手中的饭票就是消息所携带的信息。
    事件是根据接收到的消息的具体信息做出的特定的处理,放在代码中是事件响应函数。上面的例子中学生拿到饭菜后吃饭就是具体的事件。
    消息机制模拟

  在这里我们以控制台输入信息模拟窗口、对话框接收鼠标、键盘等消息,以ArrayBlockingQueue对象存放消息队列。在控制台中输入一个数值和一个字符串代表一个消息,输入-1结束输入。模拟代码如下:
  1. package message;

  2. import java.util.Queue;
  3. import java.util.Scanner;
  4. import java.util.concurrent.ArrayBlockingQueue;

  5. /**
  6. * 消息
  7. * @author luoweifu
  8. */
  9. class Message {
  10.     //消息类型
  11.     public static final int KEY_MSG = 1;
  12.     public static final int MOUSE_MSG = 2;
  13.     public static final int SYS_MSG = 3;

  14.     private Object source;  //来源
  15.     private int type;       //类型
  16.     private String info;    //信息

  17.     public Message(Object source, int type, String info) {
  18.         super();
  19.         this.source = source;
  20.         this.type = type;
  21.         this.info = info;
  22.     }

  23.     public Object getSource() {
  24.         return source;
  25.     }
  26.     public void setSource(Object source) {
  27.         this.source = source;
  28.     }
  29.     public int getType() {
  30.         return type;
  31.     }
  32.     public void setType(int type) {
  33.         this.type = type;
  34.     }
  35.     public String getInfo() {
  36.         return info;
  37.     }
  38.     public void setInfo(String info) {
  39.         this.info = info;
  40.     }
  41.     public static int getKeyMsg() {
  42.         return KEY_MSG;
  43.     }
  44.     public static int getMouseMsg() {
  45.         return MOUSE_MSG;
  46.     }
  47.     public static int getSysMsg() {
  48.         return SYS_MSG;
  49.     }
  50. }

  51. interface MessageProcess {
  52.     public void doMessage(Message msg);
  53. }

  54. /**
  55. * 窗口模拟类
  56. */
  57. class WindowSimulator implements MessageProcess{
  58.     private ArrayBlockingQueue msgQueue;
  59.     public WindowSimulator(ArrayBlockingQueue msgQueue) {
  60.         this.msgQueue = msgQueue;
  61.     }

  62.     public void GenerateMsg() {
  63.         while(true) {
  64.             Scanner scanner = new Scanner(System.in);
  65.             int msgType = scanner.nextInt();
  66.             if(msgType < 0) {           //输入负数结束循环
  67.                 break;
  68.             }
  69.             String msgInfo = scanner.next();
  70.             Message msg = new Message(this, msgType, msgInfo);
  71.             try {
  72.                 msgQueue.put(msg);      //新消息加入到队尾
  73.             } catch (InterruptedException e) {
  74.                 e.printStackTrace();
  75.             }
  76.         }
  77.     }

  78.     @Override
  79.     /**
  80.      * 消息处理
  81.      */
  82.     public void doMessage(Message msg) {
  83.         switch(msg.getType()) {
  84.         case Message.KEY_MSG:
  85.             onKeyDown(msg);
  86.             break;
  87.         case Message.MOUSE_MSG:
  88.             onMouseDown(msg);
  89.             break;
  90.         default:
  91.             onSysEvent(msg);
  92.         }
  93.     }

  94.     //键盘事件
  95.     public static void onKeyDown(Message msg) {
  96.         System.out.println("键盘事件:");
  97.         System.out.println("type:" + msg.getType());
  98.         System.out.println("info:" + msg.getInfo());
  99.     }

  100.     //鼠标事件
  101.     public static void onMouseDown(Message msg) {
  102.         System.out.println("鼠标事件:");
  103.         System.out.println("type:" + msg.getType());
  104.         System.out.println("info:" + msg.getInfo());
  105.     }

  106.     //操作系统产生的消息
  107.     public static void onSysEvent(Message msg) {
  108.         System.out.println("系统事件:");
  109.         System.out.println("type:" + msg.getType());
  110.         System.out.println("info:" + msg.getInfo());
  111.     }
  112. }

  113. /**
  114. * 消息模拟
  115. * @author luoweifu
  116. */
  117. public class MessageSimulator {
  118.     //消息队列
  119.     private static ArrayBlockingQueue<Message> messageQueue = new ArrayBlockingQueue<Message>(100);

  120.     public static void main(String[] args) {
  121.         WindowSimulator generator = new WindowSimulator(messageQueue);
  122.         //产生消息
  123.         generator.GenerateMsg();

  124.         //消息循环
  125.         Message msg = null;
  126.         while((msg = messageQueue.poll()) != null) {
  127.             ((MessageProcess) msg.getSource()).doMessage(msg);
  128.         }
  129.     }
  130. }
复制代码
这里模拟用例中只有一个消息输入源,且是一种线程阻塞的,只有输入结束后才会进行消息的处理。真实的Windows操作系统中的消息机制会有多个消息输入源,且消息输入的同时也能进行消息的处理。



上一篇:Migrating EJB2 Entity Beans to EJB3 and JPA
下一篇:高清屏概念解析与检测设备像素比的方法
傾城的日光丶 发表于 2016-10-6 09:45:29
这世界上有两个我,一个假装快乐,一个真心难过。
回复 支持 反对

使用道具 举报

精品手机App 发表于 2016-10-8 05:57:16
如果回帖是一种美德,那精品手机App早就成为圣人了!  
回复 支持 反对

使用道具 举报

2698598 发表于 2016-10-10 10:33:25
一脸的虚假繁荣。
回复 支持 反对

使用道具 举报

yzak1234 发表于 2016-11-15 19:51:38
药药,切克闹!!
回复 支持 反对

使用道具 举报

陈继飞 发表于 2016-11-16 10:05:17
过去的事情可以不忘记,但一定要放下。
回复 支持 反对

使用道具 举报

xiangyu5412 发表于 2016-11-19 22:58:55
很累,感觉不会再爱了!
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )

© 2001-2017 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表