快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

Java 性能优化技巧集锦 (6)

5. 延迟重画操作

对于图形用户界面的应用来说,性能低下的主要原因往往可以归结为重画屏幕的效率低下。当用户改变窗口大小或者滚动一个窗口时,这一点通常可以很明显地观察到。改变窗口大小或者滚动屏幕之类的操作导致重画屏幕事件大量地、迅速地生成,甚至超过了相关代码的执行速度。对付这个问题最好的办法是忽略所有“迟到”的事件。

建议在这里引入一个数毫秒的时差,即假如我们立刻接收到了另一个重画事件,可以停止处理当前事件转而处理最后一个收到的重画事件;否则,我们继承进行当前的重画过程。

假如事件要启动一项耗时的工作,分离出一个工作线程是一种较好的处理方法;否则,一些部件可能被“冻结”,因为每次只能处理一个事件。下面提供了一个事件处理的简朴例子,但经过扩展后它可以用来控制工作线程。


public static void runOnce(String id, final long milliseconds) {
synchronized(e_queue) {
// e_queue: 所有事件的集合
if (!e_queue.containsKey(id)) {
e_queue.put(token, new LastOne());
}
}
final LastOne lastOne = (LastOne) e_queue.get(token);
final long time = System.currentTimeMillis(); // 获得当前时间
lastOne.time = time;
(new Thread() {public void run() {
if (milliseconds > 0) {
try {Thread.sleep(milliseconds);} // 暂停线程
catch (Exception ex) {}
}
synchronized(lastOne.running) { // 等待上一事件结束
if (lastOne.time != time) // 只处理最后一个事件
return;
}
}}).start();
}
private static Hashtable e_queue = new Hashtable(); private static class LastOne {
public long time=0;
public Object running = new Object();
}






6. 使用双缓冲区

在屏幕之外的缓冲区绘图,完成后立刻把整个图形显示出来。由于有两个缓冲区,所以程序可以往返切换。这样,我们可以用一个低优先级的线程负责画图,使得程序能够利用空闲的CPU时间执行其他任务。下面的伪代码片断示范了这种技术。


Graphics myGraphics;
Image myOffscreenImage = createImage(size().width, size().height);
Graphics offscreenGraphics = myOffscreenImage.getGraphics();
offscreenGraphics.drawImage(img, 50, 50, this);
myGraphics.drawImage(myOffscreenImage, 0, 0, this);




7. 使用BufferedImage

Java JDK 1.2使用了一个软显示设备,使得文本在不同的平台上看起来相似。为实现这个功能,Java必须直接处理构成文字的像素。由于这种技术要在内存中大量地进行位复制操作,早期的JDK在使用这种技术时性能不佳。为解决这个问题而提出的Java标准实现了一种新的图形类型,即BufferedImage。BufferedImage子类描述的图形带有一个可访问的图形数据缓冲区。一个BufferedImage包含一个ColorModel和一组光栅图形数据。这个类一般使用RGB(红、绿、蓝)颜色模型,但也可以处理灰度级图形。它的构造函数很简朴,如下所示:


public BufferedImage (int width, int height, int imageType)




ImageType答应我们指定要缓冲的是什么类型的图形,比如5-位RGB、8-位RGB、灰度级等。



8. 使用VolatileImage

许多硬件平台和它们的操作系统都提供基本的硬件加速支持。例如,硬件加速一般提供矩形填充功能,和利用CPU完成同一任务相比,硬件加速的效率更高。由于硬件加速分离了一部分工作,答应多个工作流并发进行,从而缓解了对CPU和系统总线的压力,使得应用能够运行得更快。利用VolatileImage可以创建硬件加速的图形以及治理图形的内容。由于它直接利用低层平台的能力,性能的改善程度主要取决于系统使用的图形适配器。VolatileImage的内容随时可能丢失,也即它是“不稳定的(volatile)”。因此,在使用图形之前,最好检查一下它的内容是否丢失。VolatileImage有两个能够检查内容是否丢失的方式:


public abstract int validate(GraphicsConfiguration gc);public abstract Boolean contentsLost();




每次从VolatileImage对象复制内容或者写入VolatileImage时,应该调用validate()方式。contentsLost()方式告诉我们,自从最后一次validate()调用之后,图形的内容是否丢失。虽然VolatileImage是一个抽象类,但不要从它这里派生子类。VolatileImage应该通过Component.createVolatileImage()或者GraphicsConfiguration.createCompatibleVolatileImage()方式创建。

9. 使用Window Blitting

进行滚动操作时,所有可见的内容一般都要重画,从而导致大量不必要的重画工作。许多操作系统的图形子系统,包括WIN32 GDI、MacOS和X/Windows,都支持Window Blitting技术。Window Blitting技术直接在屏幕缓冲区中把图形移到新的位置,只重画新出现的区域。要在Swing应用中使用Window Blitting技术,设置方式如下:


setScrollMode(int mode);




在大多数应用中,使用这种技术能够提高滚动速度。只有在一种情形下,Window Blitting会导致性能降低,即应用在后台进行滚动操作。假如是用户在滚动一个应用,那么它总是在前台,无需担心任何负面影响。(T117)

(原作者:Java Research)




返回类别: 教程
上一教程: int 和 String 互相转变的多种方式 (转)
下一教程: Eclipse Form程序设计指南(3)

您可以阅读与"Java 性能优化技巧集锦 (6)"相关的教程:
· Java 性能优化技巧集锦 (5)
· Java 性能优化技巧集锦 (2)
· Java性能优化技巧集锦
· Java 性能优化技巧集锦 (1)
· Java 性能优化技巧集锦 (3)
    微笑服务 优质保证 索取样品