大量数据刷新界面时候,放置GUI软件界面僵死

GUI软件开发中,当后台有大量的数据更新需要刷新界面时,往往造成界面假死现象,此时用户的任何鼠标和键盘操作都无效。这种情况一直困扰着许多GUI软件的开发人员。

笔者最近正在参与开发一套证券交易系统的客户端, 主要面向日本市场。对于机构用户来讲,几千条甚至上万条的交易数据是很平常的。本系统的Server和client端全部实现消息通讯机制,不通过数据库交换数据。因此当有用户做了几千条交易后(Basket Trade),往往消息的更新量会达到2-3万条。Client端每收到一条消息都会计算并更新GUI界面。

本次笔者开发的客户端使用JAVA的SWING开发的,熟悉SWING的开发人员都知道,所有的GUI的更新都是被放到主线程队列里的。因此当有太多的数据更新时,会造成主线程把系统CPU用完,其它任何操作没办法得到系统时间,而造成软件假死现象。

对于本次开发出现的情况,笔者所在的开发小组曾尝试用很多方法去解决,但都实现的不理想。

最后发现一种比较正确的方法, 其时就是利用了天平的杠杆原理和信号量机制。具体实现见下图:

 具体实现细节如下:

1. 创建一线程队列, 当都新消息来时,放入队列。队列中有一run方法会不断从队列中取出最早的消息,处理后放到主线程,由主线程实现GUI显示刷新。

2. 利用信号量V,V的初始值设为1, 当run方法从队列中取出一个消息后,V减1。 消息计算完后,放入主线程执行,当主线程对改消息处理完后,在主线程里使V加1。 因此,当V=0的时候,run方法一直为阻塞的,w无法把下一个消息放入主线程处理,这样有效的降低的主线程的负载。

这种方法的精髓实际上是把界面操作和数据的GUI刷新作为天平的两头,因为这两个事件都是在主线程中做的,而主线程在某台机器上的效率是有限的且为固定数值。我们假设主线程每秒可以处理20个事件,那么如果数据的GUI刷新事件接近20时,界面的操作(键盘、鼠标)必然没法处理。
所以采用这种模型后,当用户用鼠标和键盘操作时,该事件会被首先放入主线程,如果有大量的界面操作事件,那么数据的GUI刷新事件就会被放入主线程队列的后部。当主线程处理完操作事件后才会处理GUI刷新事件,然而GUI刷新事件不处理完, V是不会加1的,下一个GUI刷新事件也不会被放入主线程执行。以此,就造成了界面操作事件和GUI刷新事件的平衡,使两种事件在任何情况下都可以得到主线程的处理,不会出现假死现象。

// Example code.
Class NewFrame extends JFrame {
 ...
    // Set default value to 1. 
    private Semaphore fSignValue = new Semaphore(1);

    class OrderQueue implements Runnable {
 private LinkedList fQueue = new LinkedList();
 
 private boolean volatile fRunningState = false;

 public synchronized addMsg(Object msg) {
  fQueue.addLast( msg );
  notify();
 }

 public synchronized Object getMsg() {
  while (fQueue.empty()) {
   wait();
  }
  return fQueue.removeFirst();
 }

 public void run() {
  fRunningState = true;
  while (!isStop()) {
   Object obj = getMsg();
   processMsg( obj );
  }
 }

 public boolean isStop() {
  return fRunningState;
 }

 public void setRunningState(final boolean state) {
  fRunningState = state;
 }
    }

    private void processMsg ( final Object obj ) {
  fSignValue.acquire();
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    try {
    // Refresh GUI by specified obj.
    // .......
    } finally {
     fSignValue.release();
    }
   }
  });
    }
}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hennylee/archive/2006/07/10/901838.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值