JSP虛擬主機,jsp空間,java空間,java虛擬空間JSP虛擬主機,jsp空間,java空間,java虛擬空間

Applet間的通訊(2)--Tricks of the Java Programming Gurus



作者:不詳    文章來源:www.933582.buzz
發布日期:2005年10月20日

    使用靜態變量進行通訊并不意味著applet就可以同時被初始化。不同的實例還是先后啟動的,我們并不能保證它們的啟動次序。然而,有一點我們可以確定:在第一個ColorRelay applet實例被創建之前,類ColorRelay已經初始化了,因此,當所有applet實例啟動時,它們都將獲得類的靜態變量。

    但是,當你使用靜態變量時必須小心,因為多個實例可能同時訪問靜態變量。為了解決這個問題,我使用了兩個同步方法(synchronized methods)從鏈表中增減applet實例。因為它們是synchronized static方法,當它們運行時,ColorRelay 類會被索住,以避免并發訪問。清單1.3是這兩個方法的代碼。值得注意的是,當第一個元素被加到鏈表之后,主控線程(controller thread)將啟動。我們隨后會看到當最后一個元素從鏈表中被移出后,這個線程將自動停止。


清單 1.3. ColorRelay.java (part 2).
    /**
     * Adds an instance to the list of active instances maintained in the
     * class.  No check is made to prevent adding the same instance twice.
     * @param elem the ColorRelay instance to add to the list.
     * @see #removeFromList
     */
    static synchronized void addToList(ColorRelay elem) {
        if (list == null) {
            list = listTail = elem;
            elem.next = elem.prev = null;

            // Because the list has elements now, we should start the thread.
            relayer = new Thread(new ColorRelay());
            relayer.start();
        }
        else {
            elem.prev = listTail;
            listTail.next = listTail = elem;
            elem.next = null;
        }
    }

    /**
     * Removes an instance from the list of active instances maintained in
     * the class.  Works properly but does <em>not</em> signal an error if
     * the element was not actually on the list.
     * @param elem the ColorRelay instance to be removed from the list.
     * @see #addToList
     */
    static synchronized void removeFromList(ColorRelay elem) {
        ColorRelay curr = list;
        while (curr != null && curr != elem) {
            curr = curr.next;
        }

        if (curr == elem) {     // We found it!
            if (list == curr) {
                list = curr.next;
            }
            if (listTail == curr) {
                listTail = curr.prev;
            }
            if (curr.next != null) {
                curr.next.prev = curr.prev;
            }
            if (curr.prev != null) {
                curr.prev.next = curr.next;
            }
            curr.next = curr.prev = null;
        }
        // If curr is null, then the element is not on the list
        // at all.  We could treat that as an error, but I'm
        // choosing to report success.

        return;
    }

初始化共享數據

    Applet被創建之后init方法被調用,這個方法檢查、轉換和存儲applet的參數。對image參數需要額外的注意,因為它是存儲在另一個靜態變量中的。在試圖訪問originalImage靜態變量之前,要鎖住ColorRelay類,我們沒有使用synchronized 方法,而是使用一段synchronized 監測語句來實現這個目的。(事實上,應該只有一個ColorRelay實例獲得image參數,但為了防止HTML中的編碼錯誤,我們采取了上述的預防措施)。清單1.4是init的代碼。


清單 1.4. ColorRelay.java (part 3).
    /**
     * Initializes the applet instance.  Checks and stores
     * parameters and initializes other instance variables.
     */
    public void init() {
        String flash = getParameter("flashColor");
        if (flash != null) {
            try {
                flashColor = new Color(parseRGB(flash));
            }
            catch (NumberFormatException e) {
                // Ignore a bad parameter and just go with the default.
            }
        }

        String sleep = getParameter("sleepTime");
        if (sleep != null) {
            try {
                sleepSecs = Integer.parseInt(sleep);
            }
            catch (NumberFormatException e) {
                // Ignore a bad parameter and just go with the default.
            }
        }
        
        String imageURL = getParameter("image");
        if (imageURL != null) {
            Class cr = Class.forName("COM.MCP.Samsnet.tjg.ColorRelay");
            synchronized (cr) {
                if (originalImage == null) {
                    originalImage = getImage(getDocumentBase(), imageURL);
                }
            }
        }

        tracker = new MediaTracker(this);
    }

Working Together

    當瀏覽器準備執行applet時,start 方法被調用,將applet加入鏈表。在stop方法中,applet被譯出鏈表。在前面的代碼中你已經看到,第一個鏈表元素的添加將導致控制線程的啟動。這個控制線程僅僅是循環讀取鏈表元素,一次將鏈表中的某個元素點亮(顯示彩色圖片)。至于顯示的持續時間,是由applet自己決定的。如果鏈表中沒有元素了,控制線程自動終止。清單1.5是控制線程的strat、stop以及run方法。


清單 1.5. ColorRelay.java (part 4).
    /**
     * Starts the applet running.  The ColorRelay hooks up with
     * other instances on the same page and begins coordinating
     * when this method is called.
     */
    public void start() {
        // Ordinarily, we want to display the original image.
        image = originalImage;

        ColorRelay.addToList(this); // Let's get to work!
    }

    /**
     * Stops the applet.  The ColorRelay instance removes itself from the
     * group of cooperating applets when this method is called.
     */
    public void  stop() {
        ColorRelay.removeFromList(this);
    }

    /**
     * Loops through the list of active instances for as long as it is
     * non-empty, calling each instance's 'flash' method.
     * @see #flash
     */
    public void run () {
        ColorRelay curr;

        // Continue running through the list until it's empty ...
        while (list != null) {
            for (curr = list; curr != null; curr = curr.next) {
                try {
                    curr.flash();
                }
                catch (InterruptedException e) {
                }
            }
        }   
    }

翻譯:chenyuan_tongji ([email protected])

Copyright © 2002-2012 JSPCN.net. All rights reserved.
JSP中文網    備案號:粵ICP備09171188號
成都恒?萍及l展有限公司    成都市一環路南二段6號新瑞樓三樓8號
在家赚钱的方法