[轉載] Java 性能優化技巧集錦 (6)

http://tech.ccidnet.com/pub/article/c1077_a199225_p6.html
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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章