首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

執行緒過多問題與平衡技術:ColorBoxes2 實戰優化

     編輯:Java 相關知識

現象:執行緒過多導致近乎停頓

在作者機器上,ColorBoxes 產生 10×10 網格後幾乎陷入停頓。懷疑 AWT 做了什麼事。以下範例測試此猜測,產生較少執行緒:將程式碼重組,讓 Vector 實作 Runnable,容納大量色塊並隨機挑選更新。建立大量 Vector 物件,數量約等於網格維度。結果:執行緒遠少於色塊數。若速度變快,證實前例執行緒過多。

ColorBoxes2 核心程式碼

//: ColorBoxes2.java
import java.awt.*;
import java.awt.event.*;
import java.util.*;

class CBox2 extends Canvas {
    private static final Color[] colors = { /* 13 種顏色 */ };
    private Color cColor = newColor();
    private static final Color newColor() { return colors[(int)(Math.random() * colors.length)]; }
    void nextColor() { cColor = newColor(); repaint(); }
    public void paint(Graphics g) {
        g.setColor(cColor);
        Dimension s = getSize();
        g.fillRect(0, 0, s.width, s.height);
    }
}

class CBoxVector extends Vector implements Runnable {
    private Thread t;
    private int pause;
    public CBoxVector(int pause) { this.pause = pause; t = new Thread(this); }
    public void go() { t.start(); }
    public void run() {
        while(true) {
            int i = (int)(Math.random() * size());
            ((CBox2)elementAt(i)).nextColor();
            try { t.sleep(pause); } catch(InterruptedException e) {}
        }
    }
}

public class ColorBoxes2 extends Frame {
    private CBoxVector[] v;
    public ColorBoxes2(int pause, int grid) {
        setTitle("ColorBoxes2");
        setLayout(new GridLayout(grid, grid));
        v = new CBoxVector[grid];
        for(int i = 0; i < grid; i++) v[i] = new CBoxVector(pause);
        for (int i = 0; i < grid * grid; i++) {
            v[i % grid].addElement(new CBox2());
            add((CBox2)v[i % grid].lastElement());
        }
        for(int i = 0; i < grid; i++) v[i].go();
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) { System.exit(0); }
        });
    }
    public static void main(String[] args) {
        int pause = 5; int grid = 8;
        if(args.length > 0) pause = Integer.parseInt(args[0]);
        if(args.length > 1) grid = Integer.parseInt(args[1]);
        Frame f = new ColorBoxes2(pause, grid);
        f.setSize(500, 400);
        f.setVisible(true);
    }
} ///:~

架構解析

  • CBox2: 類似 CBox,隨機顏色繪製自己,僅此而已
  • CBoxVector: 繼承 Vector 實作 Runnable,所有執行緒處理移至此處。run() 隨機選擇 Vector 元素呼叫 nextColor()
  • 主程式: 建立 CBoxVector 陣列,每個網格知道睡眠時間。為每個 Vector 添加等量 CBox2,啟動各自執行緒

實測結果與多執行緒效能檢查清單

運行發現:確實更快、回應更迅速(中斷時能更快停下)。隨網格尺寸增大,不會頻繁陷入「停頓」。

新考慮因素:必須隨時檢查是否有「太多執行緒」(視程式與平台)。若過多,嘗試上述技術「平衡」執行緒數量。遇到多執行緒效能問題時檢查:

  1. sleep、yield()、wait() 呼叫是否足夠?
  2. sleep() 時間是否足夠長?
  3. 運行執行緒數是否太多?
  4. 試過不同平台與 JVM?

這些問題正是多執行緒應用程式編寫成為「技術活」的原因之一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved